1
2
3
4
5
6#include <common.h>
7#include <fsl_ddr_sdram.h>
8
9#include <fsl_ddr.h>
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32static unsigned long long
33compute_ranksize(unsigned int mem_type, unsigned char row_dens)
34{
35 unsigned long long bsize;
36
37
38 bsize = ((row_dens >> 5) | ((row_dens & 31) << 3));
39 bsize <<= 27ULL;
40 debug("DDR: DDR II rank density = 0x%16llx\n", bsize);
41
42 return bsize;
43}
44
45
46
47
48
49
50
51
52
53
54
55static unsigned int
56convert_bcd_tenths_to_cycle_time_ps(unsigned int spd_val)
57{
58
59 unsigned int tenths_ps[16] = {
60 0,
61 100,
62 200,
63 300,
64 400,
65 500,
66 600,
67 700,
68 800,
69 900,
70 250,
71 330,
72 660,
73 750,
74 0,
75 0
76 };
77
78 unsigned int whole_ns = (spd_val & 0xF0) >> 4;
79 unsigned int tenth_ns = spd_val & 0x0F;
80 unsigned int ps = whole_ns * 1000 + tenths_ps[tenth_ns];
81
82 return ps;
83}
84
85static unsigned int
86convert_bcd_hundredths_to_cycle_time_ps(unsigned int spd_val)
87{
88 unsigned int tenth_ns = (spd_val & 0xF0) >> 4;
89 unsigned int hundredth_ns = spd_val & 0x0F;
90 unsigned int ps = tenth_ns * 100 + hundredth_ns * 10;
91
92 return ps;
93}
94
95static unsigned int byte40_table_ps[8] = {
96 0,
97 250,
98 330,
99 500,
100 660,
101 750,
102 0,
103 0
104};
105
106static unsigned int
107compute_trfc_ps_from_spd(unsigned char trctrfc_ext, unsigned char trfc)
108{
109 return (((trctrfc_ext & 0x1) * 256) + trfc) * 1000
110 + byte40_table_ps[(trctrfc_ext >> 1) & 0x7];
111}
112
113static unsigned int
114compute_trc_ps_from_spd(unsigned char trctrfc_ext, unsigned char trc)
115{
116 return trc * 1000 + byte40_table_ps[(trctrfc_ext >> 4) & 0x7];
117}
118
119
120
121
122
123
124static unsigned int
125determine_refresh_rate_ps(const unsigned int spd_refresh)
126{
127 unsigned int refresh_time_ps[8] = {
128 15625000,
129 3900000,
130 7800000,
131 31300000,
132 62500000,
133 125000000,
134 15625000,
135 15625000,
136 };
137
138 return refresh_time_ps[spd_refresh & 0x7];
139}
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168unsigned short ddr2_speed_bins[] = { 0, 5000, 3750, 3000, 2500, 1875 };
169
170unsigned int
171compute_derated_DDR2_CAS_latency(unsigned int mclk_ps)
172{
173 const unsigned int num_speed_bins = ARRAY_SIZE(ddr2_speed_bins);
174 unsigned int lowest_tCKmin_found = 0;
175 unsigned int lowest_tCKmin_CL = 0;
176 unsigned int i;
177
178 debug("mclk_ps = %u\n", mclk_ps);
179
180 for (i = 0; i < num_speed_bins; i++) {
181 unsigned int x = ddr2_speed_bins[i];
182 debug("i=%u, x = %u, lowest_tCKmin_found = %u\n",
183 i, x, lowest_tCKmin_found);
184 if (x && x <= mclk_ps && x >= lowest_tCKmin_found ) {
185 lowest_tCKmin_found = x;
186 lowest_tCKmin_CL = i + 2;
187 }
188 }
189
190 debug("lowest_tCKmin_CL = %u\n", lowest_tCKmin_CL);
191
192 return lowest_tCKmin_CL;
193}
194
195
196
197
198
199
200
201
202
203unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
204 const ddr2_spd_eeprom_t *spd,
205 dimm_params_t *pdimm,
206 unsigned int dimm_number)
207{
208 unsigned int retval;
209
210 if (spd->mem_type) {
211 if (spd->mem_type != SPD_MEMTYPE_DDR2) {
212 printf("DIMM %u: is not a DDR2 SPD.\n", dimm_number);
213 return 1;
214 }
215 } else {
216 memset(pdimm, 0, sizeof(dimm_params_t));
217 return 1;
218 }
219
220 retval = ddr2_spd_check(spd);
221 if (retval) {
222 printf("DIMM %u: failed checksum\n", dimm_number);
223 return 2;
224 }
225
226
227
228
229
230
231 memset(pdimm->mpart, 0, sizeof(pdimm->mpart));
232 memcpy(pdimm->mpart, spd->mpart, sizeof(pdimm->mpart) - 1);
233
234
235 pdimm->n_ranks = (spd->mod_ranks & 0x7) + 1;
236 pdimm->rank_density = compute_ranksize(spd->mem_type, spd->rank_dens);
237 pdimm->capacity = pdimm->n_ranks * pdimm->rank_density;
238 pdimm->data_width = spd->dataw;
239 pdimm->primary_sdram_width = spd->primw;
240 pdimm->ec_sdram_width = spd->ecw;
241
242
243 switch (spd->dimm_type) {
244 case DDR2_SPD_DIMMTYPE_RDIMM:
245 case DDR2_SPD_DIMMTYPE_72B_SO_RDIMM:
246 case DDR2_SPD_DIMMTYPE_MINI_RDIMM:
247
248 pdimm->registered_dimm = 1;
249 break;
250
251 case DDR2_SPD_DIMMTYPE_UDIMM:
252 case DDR2_SPD_DIMMTYPE_SO_DIMM:
253 case DDR2_SPD_DIMMTYPE_MICRO_DIMM:
254 case DDR2_SPD_DIMMTYPE_MINI_UDIMM:
255
256 pdimm->registered_dimm = 0;
257 break;
258
259 case DDR2_SPD_DIMMTYPE_72B_SO_CDIMM:
260 default:
261 printf("unknown dimm_type 0x%02X\n", spd->dimm_type);
262 return 1;
263 }
264
265
266 pdimm->n_row_addr = spd->nrow_addr;
267 pdimm->n_col_addr = spd->ncol_addr;
268 pdimm->n_banks_per_sdram_device = spd->nbanks;
269 pdimm->edc_config = spd->config;
270 pdimm->burst_lengths_bitmask = spd->burstl;
271
272
273
274
275
276
277 pdimm->tckmin_x_ps
278 = convert_bcd_tenths_to_cycle_time_ps(spd->clk_cycle);
279 pdimm->tckmin_x_minus_1_ps
280 = convert_bcd_tenths_to_cycle_time_ps(spd->clk_cycle2);
281 pdimm->tckmin_x_minus_2_ps
282 = convert_bcd_tenths_to_cycle_time_ps(spd->clk_cycle3);
283
284 pdimm->tckmax_ps = convert_bcd_tenths_to_cycle_time_ps(spd->tckmax);
285
286
287
288
289
290
291
292
293 pdimm->caslat_x = __ilog2(spd->cas_lat);
294 pdimm->caslat_x_minus_1 = __ilog2(spd->cas_lat
295 & ~(1 << pdimm->caslat_x));
296 pdimm->caslat_x_minus_2 = __ilog2(spd->cas_lat
297 & ~(1 << pdimm->caslat_x)
298 & ~(1 << pdimm->caslat_x_minus_1));
299
300
301 pdimm->caslat_lowest_derated = compute_derated_DDR2_CAS_latency(
302 get_memory_clk_period_ps(ctrl_num));
303
304
305 pdimm->trcd_ps = spd->trcd * 250;
306 pdimm->trp_ps = spd->trp * 250;
307 pdimm->tras_ps = spd->tras * 1000;
308
309 pdimm->twr_ps = spd->twr * 250;
310 pdimm->twtr_ps = spd->twtr * 250;
311 pdimm->trfc_ps = compute_trfc_ps_from_spd(spd->trctrfc_ext, spd->trfc);
312
313 pdimm->trrd_ps = spd->trrd * 250;
314 pdimm->trc_ps = compute_trc_ps_from_spd(spd->trctrfc_ext, spd->trc);
315
316 pdimm->refresh_rate_ps = determine_refresh_rate_ps(spd->refresh);
317
318 pdimm->tis_ps = convert_bcd_hundredths_to_cycle_time_ps(spd->ca_setup);
319 pdimm->tih_ps = convert_bcd_hundredths_to_cycle_time_ps(spd->ca_hold);
320 pdimm->tds_ps
321 = convert_bcd_hundredths_to_cycle_time_ps(spd->data_setup);
322 pdimm->tdh_ps
323 = convert_bcd_hundredths_to_cycle_time_ps(spd->data_hold);
324
325 pdimm->trtp_ps = spd->trtp * 250;
326 pdimm->tdqsq_max_ps = spd->tdqsq * 10;
327 pdimm->tqhs_ps = spd->tqhs * 10;
328
329 return 0;
330}
331