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