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