1 /* 2 * Copyright 2009-2010 Freescale Semiconductor, Inc. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * Version 2 as published by the Free Software Foundation. 7 */ 8 9 #include <common.h> 10 #include <i2c.h> 11 12 #include <asm/fsl_ddr_sdram.h> 13 #include <asm/fsl_ddr_dimm_params.h> 14 15 static void get_spd(ddr3_spd_eeprom_t *spd, unsigned char i2c_address) 16 { 17 int ret; 18 19 ret = i2c_read(i2c_address, 0, 1, (uchar *)spd, sizeof(ddr3_spd_eeprom_t)); 20 if (ret) { 21 debug("DDR: failed to read SPD from address %u\n", i2c_address); 22 memset(spd, 0, sizeof(ddr3_spd_eeprom_t)); 23 } 24 } 25 26 unsigned int fsl_ddr_get_mem_data_rate(void) 27 { 28 return get_ddr_freq(0); 29 } 30 31 void fsl_ddr_get_spd(ddr3_spd_eeprom_t *ctrl_dimms_spd, 32 unsigned int ctrl_num) 33 { 34 unsigned int i; 35 unsigned int i2c_address = 0; 36 37 for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) { 38 if (ctrl_num == 0 && i == 0) 39 i2c_address = SPD_EEPROM_ADDRESS1; 40 else if (ctrl_num == 1 && i == 0) 41 i2c_address = SPD_EEPROM_ADDRESS2; 42 43 get_spd(&(ctrl_dimms_spd[i]), i2c_address); 44 } 45 } 46 47 typedef struct { 48 u32 datarate_mhz_low; 49 u32 datarate_mhz_high; 50 u32 n_ranks; 51 u32 clk_adjust; 52 u32 cpo; 53 u32 write_data_delay; 54 u32 force_2T; 55 } board_specific_parameters_t; 56 57 /* ranges for parameters: 58 * wr_data_delay = 0-6 59 * clk adjust = 0-8 60 * cpo 2-0x1E (30) 61 */ 62 63 64 /* XXX: these values need to be checked for all interleaving modes. */ 65 /* XXX: No reliable dual-rank 800 MHz setting has been found. It may 66 * seem reliable, but errors will appear when memory intensive 67 * program is run. */ 68 /* XXX: Single rank at 800 MHz is OK. */ 69 const board_specific_parameters_t board_specific_parameters[][30] = { 70 { 71 /* memory controller 0 */ 72 /* lo| hi| num| clk| cpo|wrdata|2T */ 73 /* mhz| mhz|ranks|adjst| | delay| */ 74 { 0, 333, 4, 6, 7, 3, 0}, 75 {334, 400, 4, 6, 9, 3, 0}, 76 {401, 549, 4, 6, 11, 3, 0}, 77 {550, 680, 4, 1, 10, 5, 0}, 78 {681, 850, 4, 1, 12, 5, 0}, 79 {851, 1050, 4, 1, 12, 5, 0}, 80 {1051, 1250, 4, 1, 15, 4, 0}, 81 {1251, 1350, 4, 1, 15, 4, 0}, 82 { 0, 333, 2, 6, 7, 3, 0}, 83 {334, 400, 2, 6, 9, 3, 0}, 84 {401, 549, 2, 6, 11, 3, 0}, 85 {550, 680, 2, 1, 10, 5, 0}, 86 {681, 850, 2, 1, 12, 5, 0}, 87 {851, 1050, 2, 1, 12, 5, 0}, 88 {1051, 1250, 2, 1, 15, 4, 0}, 89 {1251, 1350, 2, 1, 15, 4, 0}, 90 { 0, 333, 1, 6, 7, 3, 0}, 91 {334, 400, 1, 6, 9, 3, 0}, 92 {401, 549, 1, 6, 11, 3, 0}, 93 {550, 680, 1, 1, 10, 5, 0}, 94 {681, 850, 1, 1, 12, 5, 0} 95 }, 96 97 { 98 /* memory controller 1 */ 99 /* lo| hi| num| clk| cpo|wrdata|2T */ 100 /* mhz| mhz|ranks|adjst| | delay| */ 101 { 0, 333, 4, 6, 7, 3, 0}, 102 {334, 400, 4, 6, 9, 3, 0}, 103 {401, 549, 4, 6, 11, 3, 0}, 104 {550, 680, 4, 1, 10, 5, 0}, 105 {681, 850, 4, 1, 12, 5, 0}, 106 {851, 1050, 4, 1, 12, 5, 0}, 107 {1051, 1250, 4, 1, 15, 4, 0}, 108 {1251, 1350, 4, 1, 15, 4, 0}, 109 { 0, 333, 2, 6, 7, 3, 0}, 110 {334, 400, 2, 6, 9, 3, 0}, 111 {401, 549, 2, 6, 11, 3, 0}, 112 {550, 680, 2, 1, 11, 6, 0}, 113 {681, 850, 2, 1, 13, 6, 0}, 114 {851, 1050, 2, 1, 13, 6, 0}, 115 {1051, 1250, 2, 1, 15, 4, 0}, 116 {1251, 1350, 2, 1, 15, 4, 0}, 117 { 0, 333, 1, 6, 7, 3, 0}, 118 {334, 400, 1, 6, 9, 3, 0}, 119 {401, 549, 1, 6, 11, 3, 0}, 120 {550, 680, 1, 1, 11, 6, 0}, 121 {681, 850, 1, 1, 13, 6, 0} 122 } 123 }; 124 125 void fsl_ddr_board_options(memctl_options_t *popts, 126 dimm_params_t *pdimm, 127 unsigned int ctrl_num) 128 { 129 const board_specific_parameters_t *pbsp = 130 &(board_specific_parameters[ctrl_num][0]); 131 u32 num_params = sizeof(board_specific_parameters[ctrl_num]) / 132 sizeof(board_specific_parameters[0][0]); 133 u32 i; 134 ulong ddr_freq; 135 136 /* set odt_rd_cfg and odt_wr_cfg. If the there is only one dimm in 137 * that controller, set odt_wr_cfg to 4 for CS0, and 0 to CS1. If 138 * there are two dimms in the controller, set odt_rd_cfg to 3 and 139 * odt_wr_cfg to 3 for the even CS, 0 for the odd CS. 140 */ 141 for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { 142 if (i&1) { /* odd CS */ 143 popts->cs_local_opts[i].odt_rd_cfg = 0; 144 popts->cs_local_opts[i].odt_wr_cfg = 1; 145 } else { /* even CS */ 146 if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) { 147 popts->cs_local_opts[i].odt_rd_cfg = 0; 148 popts->cs_local_opts[i].odt_wr_cfg = 1; 149 } else if (CONFIG_DIMM_SLOTS_PER_CTLR == 2) { 150 popts->cs_local_opts[i].odt_rd_cfg = 3; 151 popts->cs_local_opts[i].odt_wr_cfg = 3; 152 } 153 } 154 } 155 156 /* Get clk_adjust, cpo, write_data_delay,2T, according to the board ddr 157 * freqency and n_banks specified in board_specific_parameters table. 158 */ 159 ddr_freq = get_ddr_freq(0) / 1000000; 160 for (i = 0; i < num_params; i++) { 161 if (ddr_freq >= pbsp->datarate_mhz_low && 162 ddr_freq <= pbsp->datarate_mhz_high && 163 pdimm->n_ranks == pbsp->n_ranks) { 164 popts->cpo_override = 0xff; /* force auto CPO calibration */ 165 popts->write_data_delay = 2; 166 popts->clk_adjust = 5; /* Force value to be 5/8 clock cycle */ 167 popts->twoT_en = pbsp->force_2T; 168 } 169 pbsp++; 170 } 171 172 /* 173 * Factors to consider for half-strength driver enable: 174 * - number of DIMMs installed 175 */ 176 popts->half_strength_driver_enable = 0; 177 /* 178 * Write leveling override 179 */ 180 popts->wrlvl_override = 1; 181 popts->wrlvl_sample = 0xa; 182 popts->wrlvl_start = 0x7; 183 /* 184 * Rtt and Rtt_WR override 185 */ 186 popts->rtt_override = 1; 187 popts->rtt_override_value = DDR3_RTT_120_OHM; 188 popts->rtt_wr_override_value = 0; /* Rtt_WR= dynamic ODT off */ 189 190 /* Enable ZQ calibration */ 191 popts->zq_en = 1; 192 } 193