1
2
3
4
5
6
7
8
9#include <common.h>
10#include <asm/fsl_ddr_sdram.h>
11
12#include "ddr.h"
13
14#if defined(CONFIG_FSL_DDR3)
15static unsigned int
16compute_cas_latency_ddr3(const dimm_params_t *dimm_params,
17 common_timing_params_t *outpdimm,
18 unsigned int number_of_dimms)
19{
20 unsigned int i;
21 unsigned int tAAmin_ps = 0;
22 unsigned int tCKmin_X_ps = 0;
23 unsigned int common_caslat;
24 unsigned int caslat_actual;
25 unsigned int retry = 16;
26 unsigned int tmp;
27 const unsigned int mclk_ps = get_memory_clk_period_ps();
28
29
30 tmp = dimm_params[0].caslat_X;
31 for (i = 1; i < number_of_dimms; i++) {
32 if (dimm_params[i].n_ranks)
33 tmp &= dimm_params[i].caslat_X;
34 }
35 common_caslat = tmp;
36
37
38 for (i = 0; i < number_of_dimms; i++) {
39 tAAmin_ps = max(tAAmin_ps, dimm_params[i].tAA_ps);
40 tCKmin_X_ps = max(tCKmin_X_ps, dimm_params[i].tCKmin_X_ps);
41 }
42
43 if (mclk_ps < tCKmin_X_ps) {
44 printf("DDR clock (MCLK cycle %u ps) is faster than "
45 "the slowest DIMM(s) (tCKmin %u ps) can support.\n",
46 mclk_ps, tCKmin_X_ps);
47 return 1;
48 }
49
50 caslat_actual = (tAAmin_ps + mclk_ps - 1) / mclk_ps;
51
52 while (!(common_caslat & (1 << caslat_actual)) && retry > 0) {
53 caslat_actual++;
54 retry--;
55 }
56
57
58
59
60 if (caslat_actual * mclk_ps > 20000) {
61 printf("The choosen cas latency %d is too large\n",
62 caslat_actual);
63 return 1;
64 }
65 outpdimm->lowest_common_SPD_caslat = caslat_actual;
66
67 return 0;
68}
69#endif
70
71
72
73
74
75
76
77
78unsigned int
79compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
80 common_timing_params_t *outpdimm,
81 const unsigned int number_of_dimms)
82{
83 unsigned int i, j;
84
85 unsigned int tCKmin_X_ps = 0;
86 unsigned int tCKmax_ps = 0xFFFFFFFF;
87 unsigned int tCKmax_max_ps = 0;
88 unsigned int tRCD_ps = 0;
89 unsigned int tRP_ps = 0;
90 unsigned int tRAS_ps = 0;
91 unsigned int tWR_ps = 0;
92 unsigned int tWTR_ps = 0;
93 unsigned int tRFC_ps = 0;
94 unsigned int tRRD_ps = 0;
95 unsigned int tRC_ps = 0;
96 unsigned int refresh_rate_ps = 0;
97 unsigned int tIS_ps = 0;
98 unsigned int tIH_ps = 0;
99 unsigned int tDS_ps = 0;
100 unsigned int tDH_ps = 0;
101 unsigned int tRTP_ps = 0;
102 unsigned int tDQSQ_max_ps = 0;
103 unsigned int tQHS_ps = 0;
104
105 unsigned int temp1, temp2;
106 unsigned int additive_latency = 0;
107#if !defined(CONFIG_FSL_DDR3)
108 const unsigned int mclk_ps = get_memory_clk_period_ps();
109 unsigned int lowest_good_caslat;
110 unsigned int not_ok;
111
112 debug("using mclk_ps = %u\n", mclk_ps);
113#endif
114
115 temp1 = 0;
116 for (i = 0; i < number_of_dimms; i++) {
117
118
119
120
121 if (dimm_params[i].n_ranks == 0) {
122 temp1++;
123 continue;
124 }
125 if (dimm_params[i].n_ranks == 4 && i != 0) {
126 printf("Found Quad-rank DIMM in wrong bank, ignored."
127 " Software may not run as expected.\n");
128 temp1++;
129 continue;
130 }
131
132
133
134
135
136
137#ifndef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE
138 if (dimm_params[i].n_ranks == 4 && \
139 CONFIG_CHIP_SELECTS_PER_CTRL/CONFIG_DIMM_SLOTS_PER_CTLR < 4) {
140 printf("Found Quad-rank DIMM, not able to support.");
141 temp1++;
142 continue;
143 }
144#endif
145
146
147
148
149 tCKmax_ps = min(tCKmax_ps, dimm_params[i].tCKmax_ps);
150
151
152
153 tCKmin_X_ps = max(tCKmin_X_ps, dimm_params[i].tCKmin_X_ps);
154 tCKmax_max_ps = max(tCKmax_max_ps, dimm_params[i].tCKmax_ps);
155 tRCD_ps = max(tRCD_ps, dimm_params[i].tRCD_ps);
156 tRP_ps = max(tRP_ps, dimm_params[i].tRP_ps);
157 tRAS_ps = max(tRAS_ps, dimm_params[i].tRAS_ps);
158 tWR_ps = max(tWR_ps, dimm_params[i].tWR_ps);
159 tWTR_ps = max(tWTR_ps, dimm_params[i].tWTR_ps);
160 tRFC_ps = max(tRFC_ps, dimm_params[i].tRFC_ps);
161 tRRD_ps = max(tRRD_ps, dimm_params[i].tRRD_ps);
162 tRC_ps = max(tRC_ps, dimm_params[i].tRC_ps);
163 tIS_ps = max(tIS_ps, dimm_params[i].tIS_ps);
164 tIH_ps = max(tIH_ps, dimm_params[i].tIH_ps);
165 tDS_ps = max(tDS_ps, dimm_params[i].tDS_ps);
166 tDH_ps = max(tDH_ps, dimm_params[i].tDH_ps);
167 tRTP_ps = max(tRTP_ps, dimm_params[i].tRTP_ps);
168 tQHS_ps = max(tQHS_ps, dimm_params[i].tQHS_ps);
169 refresh_rate_ps = max(refresh_rate_ps,
170 dimm_params[i].refresh_rate_ps);
171
172
173
174
175
176
177
178 tDQSQ_max_ps = max(tDQSQ_max_ps, dimm_params[i].tDQSQ_max_ps);
179 }
180
181 outpdimm->ndimms_present = number_of_dimms - temp1;
182
183 if (temp1 == number_of_dimms) {
184 debug("no dimms this memory controller\n");
185 return 0;
186 }
187
188 outpdimm->tCKmin_X_ps = tCKmin_X_ps;
189 outpdimm->tCKmax_ps = tCKmax_ps;
190 outpdimm->tCKmax_max_ps = tCKmax_max_ps;
191 outpdimm->tRCD_ps = tRCD_ps;
192 outpdimm->tRP_ps = tRP_ps;
193 outpdimm->tRAS_ps = tRAS_ps;
194 outpdimm->tWR_ps = tWR_ps;
195 outpdimm->tWTR_ps = tWTR_ps;
196 outpdimm->tRFC_ps = tRFC_ps;
197 outpdimm->tRRD_ps = tRRD_ps;
198 outpdimm->tRC_ps = tRC_ps;
199 outpdimm->refresh_rate_ps = refresh_rate_ps;
200 outpdimm->tIS_ps = tIS_ps;
201 outpdimm->tIH_ps = tIH_ps;
202 outpdimm->tDS_ps = tDS_ps;
203 outpdimm->tDH_ps = tDH_ps;
204 outpdimm->tRTP_ps = tRTP_ps;
205 outpdimm->tDQSQ_max_ps = tDQSQ_max_ps;
206 outpdimm->tQHS_ps = tQHS_ps;
207
208
209 temp1 = 0xff;
210 for (i = 0; i < number_of_dimms; i++) {
211 if (dimm_params[i].n_ranks) {
212 temp1 &= dimm_params[i].burst_lengths_bitmask;
213 }
214 }
215 outpdimm->all_DIMMs_burst_lengths_bitmask = temp1;
216
217
218 temp1 = temp2 = 0;
219 for (i = 0; i < number_of_dimms; i++) {
220 if (dimm_params[i].n_ranks) {
221 if (dimm_params[i].registered_dimm) {
222 temp1 = 1;
223 printf("Detected RDIMM %s\n",
224 dimm_params[i].mpart);
225 } else {
226 temp2 = 1;
227 printf("Detected UDIMM %s\n",
228 dimm_params[i].mpart);
229 }
230 }
231 }
232
233 outpdimm->all_DIMMs_registered = 0;
234 outpdimm->all_DIMMs_unbuffered = 0;
235 if (temp1 && !temp2) {
236 outpdimm->all_DIMMs_registered = 1;
237 } else if (!temp1 && temp2) {
238 outpdimm->all_DIMMs_unbuffered = 1;
239 } else {
240 printf("ERROR: Mix of registered buffered and unbuffered "
241 "DIMMs detected!\n");
242 }
243
244 temp1 = 0;
245 if (outpdimm->all_DIMMs_registered)
246 for (j = 0; j < 16; j++) {
247 outpdimm->rcw[j] = dimm_params[0].rcw[j];
248 for (i = 1; i < number_of_dimms; i++) {
249 if (!dimm_params[i].n_ranks)
250 continue;
251 if (dimm_params[i].rcw[j] != dimm_params[0].rcw[j]) {
252 temp1 = 1;
253 break;
254 }
255 }
256 }
257
258 if (temp1 != 0)
259 printf("ERROR: Mix different RDIMM detected!\n");
260
261#if defined(CONFIG_FSL_DDR3)
262 if (compute_cas_latency_ddr3(dimm_params, outpdimm, number_of_dimms))
263 return 1;
264#else
265
266
267
268
269
270
271
272
273
274
275
276 temp1 = 0xFF;
277 for (i = 0; i < number_of_dimms; i++) {
278 if (dimm_params[i].n_ranks) {
279 temp2 = 0;
280 temp2 |= 1 << dimm_params[i].caslat_X;
281 temp2 |= 1 << dimm_params[i].caslat_X_minus_1;
282 temp2 |= 1 << dimm_params[i].caslat_X_minus_2;
283
284
285
286
287
288
289
290
291
292
293
294 temp1 &= temp2;
295 }
296 }
297
298
299
300
301
302 lowest_good_caslat = 0;
303 temp2 = 0;
304 while (temp1) {
305 not_ok = 0;
306 temp2 = __ilog2(temp1);
307 debug("checking common caslat = %u\n", temp2);
308
309
310 for (i = 0; i < number_of_dimms; i++) {
311 if (!dimm_params[i].n_ranks) {
312 continue;
313 }
314 if (dimm_params[i].caslat_X == temp2) {
315 if (mclk_ps >= dimm_params[i].tCKmin_X_ps) {
316 debug("CL = %u ok on DIMM %u at tCK=%u"
317 " ps with its tCKmin_X_ps of %u\n",
318 temp2, i, mclk_ps,
319 dimm_params[i].tCKmin_X_ps);
320 continue;
321 } else {
322 not_ok++;
323 }
324 }
325
326 if (dimm_params[i].caslat_X_minus_1 == temp2) {
327 unsigned int tCKmin_X_minus_1_ps
328 = dimm_params[i].tCKmin_X_minus_1_ps;
329 if (mclk_ps >= tCKmin_X_minus_1_ps) {
330 debug("CL = %u ok on DIMM %u at "
331 "tCK=%u ps with its "
332 "tCKmin_X_minus_1_ps of %u\n",
333 temp2, i, mclk_ps,
334 tCKmin_X_minus_1_ps);
335 continue;
336 } else {
337 not_ok++;
338 }
339 }
340
341 if (dimm_params[i].caslat_X_minus_2 == temp2) {
342 unsigned int tCKmin_X_minus_2_ps
343 = dimm_params[i].tCKmin_X_minus_2_ps;
344 if (mclk_ps >= tCKmin_X_minus_2_ps) {
345 debug("CL = %u ok on DIMM %u at "
346 "tCK=%u ps with its "
347 "tCKmin_X_minus_2_ps of %u\n",
348 temp2, i, mclk_ps,
349 tCKmin_X_minus_2_ps);
350 continue;
351 } else {
352 not_ok++;
353 }
354 }
355 }
356
357 if (!not_ok) {
358 lowest_good_caslat = temp2;
359 }
360
361 temp1 &= ~(1 << temp2);
362 }
363
364 debug("lowest common SPD-defined CAS latency = %u\n",
365 lowest_good_caslat);
366 outpdimm->lowest_common_SPD_caslat = lowest_good_caslat;
367
368
369
370
371
372
373
374
375
376 temp1 = 0;
377 for (i = 0; i < number_of_dimms; i++) {
378 temp1 = max(temp1, dimm_params[i].caslat_lowest_derated);
379 }
380 outpdimm->highest_common_derated_caslat = temp1;
381 debug("highest common dereated CAS latency = %u\n", temp1);
382#endif
383
384
385 temp1 = 1;
386 for (i = 0; i < number_of_dimms; i++) {
387 if (dimm_params[i].n_ranks &&
388 !(dimm_params[i].edc_config & EDC_ECC)) {
389 temp1 = 0;
390 break;
391 }
392 }
393 if (temp1) {
394 debug("all DIMMs ECC capable\n");
395 } else {
396 debug("Warning: not all DIMMs ECC capable, cant enable ECC\n");
397 }
398 outpdimm->all_DIMMs_ECC_capable = temp1;
399
400#ifndef CONFIG_FSL_DDR3
401
402 if (mclk_ps > tCKmax_max_ps) {
403 printf("Warning: some of the installed DIMMs "
404 "can not operate this slowly.\n");
405 return 1;
406 }
407#endif
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461 additive_latency = 0;
462
463#if defined(CONFIG_FSL_DDR2)
464 if (lowest_good_caslat < 4) {
465 additive_latency = (picos_to_mclk(tRCD_ps) > lowest_good_caslat)
466 ? picos_to_mclk(tRCD_ps) - lowest_good_caslat : 0;
467 if (mclk_to_picos(additive_latency) > tRCD_ps) {
468 additive_latency = picos_to_mclk(tRCD_ps);
469 debug("setting additive_latency to %u because it was "
470 " greater than tRCD_ps\n", additive_latency);
471 }
472 }
473
474#elif defined(CONFIG_FSL_DDR3)
475
476
477
478
479 additive_latency = 0;
480#endif
481
482
483
484
485
486
487
488 if (mclk_to_picos(additive_latency) > tRCD_ps) {
489 printf("Error: invalid additive latency exceeds tRCD(min).\n");
490 return 1;
491 }
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506 outpdimm->additive_latency = additive_latency;
507
508 debug("tCKmin_ps = %u\n", outpdimm->tCKmin_X_ps);
509 debug("tRCD_ps = %u\n", outpdimm->tRCD_ps);
510 debug("tRP_ps = %u\n", outpdimm->tRP_ps);
511 debug("tRAS_ps = %u\n", outpdimm->tRAS_ps);
512 debug("tWR_ps = %u\n", outpdimm->tWR_ps);
513 debug("tWTR_ps = %u\n", outpdimm->tWTR_ps);
514 debug("tRFC_ps = %u\n", outpdimm->tRFC_ps);
515 debug("tRRD_ps = %u\n", outpdimm->tRRD_ps);
516 debug("tRC_ps = %u\n", outpdimm->tRC_ps);
517
518 return 0;
519}
520