blob: 0e11b434ab67c3653101db24222d70348d2b2d02 [file] [log] [blame]
Stefan Roese5ffceb82015-03-26 15:36:56 +01001/*
2 * Copyright (C) Marvell International Ltd. and its affiliates
3 *
4 * SPDX-License-Identifier: GPL-2.0
5 */
6
7#include <common.h>
8#include <spl.h>
9#include <asm/io.h>
10#include <asm/arch/cpu.h>
11#include <asm/arch/soc.h>
12
13#include "ddr3_init.h"
14
15/* List of allowed frequency listed in order of enum hws_ddr_freq */
16u32 freq_val[DDR_FREQ_LIMIT] = {
17 0, /*DDR_FREQ_LOW_FREQ */
18 400, /*DDR_FREQ_400, */
19 533, /*DDR_FREQ_533, */
20 666, /*DDR_FREQ_667, */
21 800, /*DDR_FREQ_800, */
22 933, /*DDR_FREQ_933, */
23 1066, /*DDR_FREQ_1066, */
24 311, /*DDR_FREQ_311, */
25 333, /*DDR_FREQ_333, */
26 467, /*DDR_FREQ_467, */
27 850, /*DDR_FREQ_850, */
28 600, /*DDR_FREQ_600 */
29 300, /*DDR_FREQ_300 */
30 900, /*DDR_FREQ_900 */
31 360, /*DDR_FREQ_360 */
32 1000 /*DDR_FREQ_1000 */
33};
34
35/* Table for CL values per frequency for each speed bin index */
36struct cl_val_per_freq cas_latency_table[] = {
37 /*
38 * 400M 667M 933M 311M 467M 600M 360
39 * 100M 533M 800M 1066M 333M 850M 900
40 * 1000 (the order is 100, 400, 533 etc.)
41 */
42 /* DDR3-800D */
43 { {6, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
44 /* DDR3-800E */
45 { {6, 6, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 6, 0, 6, 0} },
46 /* DDR3-1066E */
47 { {6, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 0, 5, 0, 5, 0} },
48 /* DDR3-1066F */
49 { {6, 6, 7, 0, 0, 0, 0, 6, 6, 7, 0, 0, 6, 0, 6, 0} },
50 /* DDR3-1066G */
51 { {6, 6, 8, 0, 0, 0, 0, 6, 6, 8, 0, 0, 6, 0, 6, 0} },
52 /* DDR3-1333F* */
53 { {6, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
54 /* DDR3-1333G */
55 { {6, 5, 7, 8, 0, 0, 0, 5, 5, 7, 0, 8, 5, 0, 5, 0} },
56 /* DDR3-1333H */
57 { {6, 6, 8, 9, 0, 0, 0, 6, 6, 8, 0, 9, 6, 0, 6, 0} },
58 /* DDR3-1333J* */
59 { {6, 6, 8, 10, 0, 0, 0, 6, 6, 8, 0, 10, 6, 0, 6, 0}
60 /* DDR3-1600G* */},
61 { {6, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
62 /* DDR3-1600H */
63 { {6, 5, 6, 8, 9, 0, 0, 5, 5, 6, 0, 8, 5, 0, 5, 0} },
64 /* DDR3-1600J */
65 { {6, 5, 7, 9, 10, 0, 0, 5, 5, 7, 0, 9, 5, 0, 5, 0} },
66 /* DDR3-1600K */
67 { {6, 6, 8, 10, 11, 0, 0, 6, 6, 8, 0, 10, 6, 0, 6, 0 } },
68 /* DDR3-1866J* */
69 { {6, 5, 6, 8, 9, 11, 0, 5, 5, 6, 11, 8, 5, 0, 5, 0} },
70 /* DDR3-1866K */
71 { {6, 5, 7, 8, 10, 11, 0, 5, 5, 7, 11, 8, 5, 11, 5, 11} },
72 /* DDR3-1866L */
73 { {6, 6, 7, 9, 11, 12, 0, 6, 6, 7, 12, 9, 6, 12, 6, 12} },
74 /* DDR3-1866M* */
75 { {6, 6, 8, 10, 11, 13, 0, 6, 6, 8, 13, 10, 6, 13, 6, 13} },
76 /* DDR3-2133K* */
77 { {6, 5, 6, 7, 9, 10, 11, 5, 5, 6, 10, 7, 5, 11, 5, 11} },
78 /* DDR3-2133L */
79 { {6, 5, 6, 8, 9, 11, 12, 5, 5, 6, 11, 8, 5, 12, 5, 12} },
80 /* DDR3-2133M */
81 { {6, 5, 7, 9, 10, 12, 13, 5, 5, 7, 12, 9, 5, 13, 5, 13} },
82 /* DDR3-2133N* */
83 { {6, 6, 7, 9, 11, 13, 14, 6, 6, 7, 13, 9, 6, 14, 6, 14} },
84 /* DDR3-1333H-ext */
85 { {6, 6, 7, 9, 0, 0, 0, 6, 6, 7, 0, 9, 6, 0, 6, 0} },
86 /* DDR3-1600K-ext */
87 { {6, 6, 7, 9, 11, 0, 0, 6, 6, 7, 0, 9, 6, 0, 6, 0} },
88 /* DDR3-1866M-ext */
89 { {6, 6, 7, 9, 11, 13, 0, 6, 6, 7, 13, 9, 6, 13, 6, 13} },
90};
91
92/* Table for CWL values per speedbin index */
93struct cl_val_per_freq cas_write_latency_table[] = {
94 /*
95 * 400M 667M 933M 311M 467M 600M 360
96 * 100M 533M 800M 1066M 333M 850M 900
97 * (the order is 100, 400, 533 etc.)
98 */
99 /* DDR3-800D */
100 { {5, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
101 /* DDR3-800E */
102 { {5, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
103 /* DDR3-1066E */
104 { {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
105 /* DDR3-1066F */
106 { {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
107 /* DDR3-1066G */
108 { {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
109 /* DDR3-1333F* */
110 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
111 /* DDR3-1333G */
112 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
113 /* DDR3-1333H */
114 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
115 /* DDR3-1333J* */
116 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
117 /* DDR3-1600G* */
118 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
119 /* DDR3-1600H */
120 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
121 /* DDR3-1600J */
122 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
123 /* DDR3-1600K */
124 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
125 /* DDR3-1866J* */
126 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 0, 5, 0} },
127 /* DDR3-1866K */
128 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 0, 5, 0} },
129 /* DDR3-1866L */
130 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
131 /* DDR3-1866M* */
132 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
133 /* DDR3-2133K* */
134 { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
135 /* DDR3-2133L */
136 { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
137 /* DDR3-2133M */
138 { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
139 /* DDR3-2133N* */
140 { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
141 /* DDR3-1333H-ext */
142 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
143 /* DDR3-1600K-ext */
144 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
145 /* DDR3-1866M-ext */
146 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
147};
148
149u8 twr_mask_table[] = {
150 10,
151 10,
152 10,
153 10,
154 10,
Chris Packham5450f0c2018-01-18 17:16:10 +1300155 1, /*5*/
156 2, /*6*/
157 3, /*7*/
158 4, /*8*/
Stefan Roese5ffceb82015-03-26 15:36:56 +0100159 10,
Chris Packham5450f0c2018-01-18 17:16:10 +1300160 5, /*10*/
Stefan Roese5ffceb82015-03-26 15:36:56 +0100161 10,
Chris Packham5450f0c2018-01-18 17:16:10 +1300162 6, /*12*/
Stefan Roese5ffceb82015-03-26 15:36:56 +0100163 10,
Chris Packham5450f0c2018-01-18 17:16:10 +1300164 7, /*14*/
Stefan Roese5ffceb82015-03-26 15:36:56 +0100165 10,
Chris Packham5450f0c2018-01-18 17:16:10 +1300166 0 /*16*/
Stefan Roese5ffceb82015-03-26 15:36:56 +0100167};
168
169u8 cl_mask_table[] = {
170 0,
171 0,
172 0,
173 0,
174 0,
175 0x2,
176 0x4,
177 0x6,
178 0x8,
179 0xa,
180 0xc,
181 0xe,
182 0x1,
183 0x3,
184 0x5,
185 0x5
186};
187
188u8 cwl_mask_table[] = {
189 0,
190 0,
191 0,
192 0,
193 0,
194 0,
195 0x1,
196 0x2,
197 0x3,
198 0x4,
199 0x5,
200 0x6,
201 0x7,
202 0x8,
203 0x9,
204 0x9
205};
206
207/* RFC values (in ns) */
208u16 rfc_table[] = {
209 90, /* 512M */
210 110, /* 1G */
211 160, /* 2G */
212 260, /* 4G */
213 350 /* 8G */
214};
215
216u32 speed_bin_table_t_rc[] = {
217 50000,
218 52500,
219 48750,
220 50625,
221 52500,
222 46500,
223 48000,
224 49500,
225 51000,
226 45000,
227 46250,
228 47500,
229 48750,
230 44700,
231 45770,
232 46840,
233 47910,
234 43285,
235 44220,
236 45155,
237 46900
238};
239
240u32 speed_bin_table_t_rcd_t_rp[] = {
241 12500,
242 15000,
243 11250,
244 13125,
245 15000,
246 10500,
247 12000,
248 13500,
249 15000,
250 10000,
251 11250,
252 12500,
253 13750,
254 10700,
255 11770,
256 12840,
257 13910,
258 10285,
259 11022,
260 12155,
261 13090,
262};
263
264enum {
265 PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR = 0,
266 PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM
267};
268
269static u8 pattern_killer_pattern_table_map[KILLER_PATTERN_LENGTH * 2][2] = {
270 /*Aggressor / Victim */
271 {1, 0},
272 {0, 0},
273 {1, 0},
274 {1, 1},
275 {0, 1},
276 {0, 1},
277 {1, 0},
278 {0, 1},
279 {1, 0},
280 {0, 1},
281 {1, 0},
282 {1, 0},
283 {0, 1},
284 {1, 0},
285 {0, 1},
286 {0, 0},
287 {1, 1},
288 {0, 0},
289 {1, 1},
290 {0, 0},
291 {1, 1},
292 {0, 0},
293 {1, 1},
294 {1, 0},
295 {0, 0},
296 {1, 1},
297 {0, 0},
298 {1, 1},
299 {0, 0},
300 {0, 0},
301 {0, 0},
302 {0, 1},
303 {0, 1},
304 {1, 1},
305 {0, 0},
306 {0, 0},
307 {1, 1},
308 {1, 1},
309 {0, 0},
310 {1, 1},
311 {0, 0},
312 {1, 1},
313 {1, 1},
314 {0, 0},
315 {0, 0},
316 {1, 1},
317 {0, 0},
318 {1, 1},
319 {0, 1},
320 {0, 0},
321 {0, 1},
322 {0, 1},
323 {0, 0},
324 {1, 1},
325 {1, 1},
326 {1, 0},
327 {1, 0},
328 {1, 1},
329 {1, 1},
330 {1, 1},
331 {1, 1},
332 {1, 1},
333 {1, 1},
334 {1, 1}
335};
336
337static u8 pattern_vref_pattern_table_map[] = {
338 /* 1 means 0xffffffff, 0 is 0x0 */
339 0xb8,
340 0x52,
341 0x55,
342 0x8a,
343 0x33,
344 0xa6,
345 0x6d,
346 0xfe
347};
348
349/* Return speed Bin value for selected index and t* element */
350u32 speed_bin_table(u8 index, enum speed_bin_table_elements element)
351{
352 u32 result = 0;
353
354 switch (element) {
355 case SPEED_BIN_TRCD:
356 case SPEED_BIN_TRP:
357 result = speed_bin_table_t_rcd_t_rp[index];
358 break;
359 case SPEED_BIN_TRAS:
360 if (index < 6)
361 result = 37500;
362 else if (index < 10)
363 result = 36000;
364 else if (index < 14)
365 result = 35000;
366 else if (index < 18)
367 result = 34000;
368 else
369 result = 33000;
370 break;
371 case SPEED_BIN_TRC:
372 result = speed_bin_table_t_rc[index];
373 break;
374 case SPEED_BIN_TRRD1K:
375 if (index < 3)
376 result = 10000;
377 else if (index < 6)
378 result = 7005;
379 else if (index < 14)
380 result = 6000;
381 else
382 result = 5000;
383 break;
384 case SPEED_BIN_TRRD2K:
385 if (index < 6)
386 result = 10000;
387 else if (index < 14)
388 result = 7005;
389 else
390 result = 6000;
391 break;
392 case SPEED_BIN_TPD:
393 if (index < 3)
394 result = 7500;
395 else if (index < 10)
396 result = 5625;
397 else
398 result = 5000;
399 break;
400 case SPEED_BIN_TFAW1K:
401 if (index < 3)
402 result = 40000;
403 else if (index < 6)
404 result = 37500;
405 else if (index < 14)
406 result = 30000;
407 else if (index < 18)
408 result = 27000;
409 else
410 result = 25000;
411 break;
412 case SPEED_BIN_TFAW2K:
413 if (index < 6)
414 result = 50000;
415 else if (index < 10)
416 result = 45000;
417 else if (index < 14)
418 result = 40000;
419 else
420 result = 35000;
421 break;
422 case SPEED_BIN_TWTR:
423 result = 7500;
424 break;
425 case SPEED_BIN_TRTP:
426 result = 7500;
427 break;
428 case SPEED_BIN_TWR:
429 result = 15000;
430 break;
431 case SPEED_BIN_TMOD:
432 result = 15000;
433 break;
Chris Packham5450f0c2018-01-18 17:16:10 +1300434 case SPEED_BIN_TXPDLL:
435 result = 24000;
436 break;
Stefan Roese5ffceb82015-03-26 15:36:56 +0100437 default:
438 break;
439 }
440
441 return result;
442}
443
444static inline u32 pattern_table_get_killer_word(u8 dqs, u8 index)
445{
446 u8 i, byte = 0;
447 u8 role;
448
449 for (i = 0; i < 8; i++) {
450 role = (i == dqs) ?
451 (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) :
452 (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM);
453 byte |= pattern_killer_pattern_table_map[index][role] << i;
454 }
455
456 return byte | (byte << 8) | (byte << 16) | (byte << 24);
457}
458
459static inline u32 pattern_table_get_killer_word16(u8 dqs, u8 index)
460{
461 u8 i, byte0 = 0, byte1 = 0;
462 u8 role;
463
464 for (i = 0; i < 8; i++) {
465 role = (i == dqs) ?
466 (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) :
467 (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM);
468 byte0 |= pattern_killer_pattern_table_map[index * 2][role] << i;
469 }
470
471 for (i = 0; i < 8; i++) {
472 role = (i == dqs) ?
473 (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) :
474 (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM);
475 byte1 |= pattern_killer_pattern_table_map
476 [index * 2 + 1][role] << i;
477 }
478
479 return byte0 | (byte0 << 8) | (byte1 << 16) | (byte1 << 24);
480}
481
482static inline u32 pattern_table_get_sso_word(u8 sso, u8 index)
483{
484 u8 step = sso + 1;
485
486 if (0 == ((index / step) & 1))
487 return 0x0;
488 else
489 return 0xffffffff;
490}
491
492static inline u32 pattern_table_get_vref_word(u8 index)
493{
494 if (0 == ((pattern_vref_pattern_table_map[index / 8] >>
495 (index % 8)) & 1))
496 return 0x0;
497 else
498 return 0xffffffff;
499}
500
501static inline u32 pattern_table_get_vref_word16(u8 index)
502{
503 if (0 == pattern_killer_pattern_table_map
504 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] &&
505 0 == pattern_killer_pattern_table_map
506 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1])
507 return 0x00000000;
508 else if (1 == pattern_killer_pattern_table_map
509 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] &&
510 0 == pattern_killer_pattern_table_map
511 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1])
512 return 0xffff0000;
513 else if (0 == pattern_killer_pattern_table_map
514 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] &&
515 1 == pattern_killer_pattern_table_map
516 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1])
517 return 0x0000ffff;
518 else
519 return 0xffffffff;
520}
521
522static inline u32 pattern_table_get_static_pbs_word(u8 index)
523{
524 u16 temp;
525
526 temp = ((0x00ff << (index / 3)) & 0xff00) >> 8;
527
528 return temp | (temp << 8) | (temp << 16) | (temp << 24);
529}
530
531inline u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
532{
533 u32 pattern;
534 struct hws_topology_map *tm = ddr3_get_topology_map();
535
536 if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask) == 0) {
537 /* 32bit patterns */
538 switch (type) {
539 case PATTERN_PBS1:
540 case PATTERN_PBS2:
541 if (index == 0 || index == 2 || index == 5 ||
542 index == 7)
543 pattern = PATTERN_55;
544 else
545 pattern = PATTERN_AA;
546 break;
547 case PATTERN_PBS3:
548 if (0 == (index & 1))
549 pattern = PATTERN_55;
550 else
551 pattern = PATTERN_AA;
552 break;
553 case PATTERN_RL:
554 if (index < 6)
555 pattern = PATTERN_00;
556 else
557 pattern = PATTERN_80;
558 break;
559 case PATTERN_STATIC_PBS:
560 pattern = pattern_table_get_static_pbs_word(index);
561 break;
562 case PATTERN_KILLER_DQ0:
563 case PATTERN_KILLER_DQ1:
564 case PATTERN_KILLER_DQ2:
565 case PATTERN_KILLER_DQ3:
566 case PATTERN_KILLER_DQ4:
567 case PATTERN_KILLER_DQ5:
568 case PATTERN_KILLER_DQ6:
569 case PATTERN_KILLER_DQ7:
570 pattern = pattern_table_get_killer_word(
571 (u8)(type - PATTERN_KILLER_DQ0), index);
572 break;
573 case PATTERN_RL2:
574 if (index < 6)
575 pattern = PATTERN_00;
576 else
577 pattern = PATTERN_01;
578 break;
579 case PATTERN_TEST:
580 if (index > 1 && index < 6)
581 pattern = PATTERN_20;
582 else
583 pattern = PATTERN_00;
584 break;
585 case PATTERN_FULL_SSO0:
586 case PATTERN_FULL_SSO1:
587 case PATTERN_FULL_SSO2:
588 case PATTERN_FULL_SSO3:
589 pattern = pattern_table_get_sso_word(
590 (u8)(type - PATTERN_FULL_SSO0), index);
591 break;
592 case PATTERN_VREF:
593 pattern = pattern_table_get_vref_word(index);
594 break;
595 default:
596 pattern = 0;
597 break;
598 }
599 } else {
600 /* 16bit patterns */
601 switch (type) {
602 case PATTERN_PBS1:
603 case PATTERN_PBS2:
604 case PATTERN_PBS3:
605 pattern = PATTERN_55AA;
606 break;
607 case PATTERN_RL:
608 if (index < 3)
609 pattern = PATTERN_00;
610 else
611 pattern = PATTERN_80;
612 break;
613 case PATTERN_STATIC_PBS:
614 pattern = PATTERN_00FF;
615 break;
616 case PATTERN_KILLER_DQ0:
617 case PATTERN_KILLER_DQ1:
618 case PATTERN_KILLER_DQ2:
619 case PATTERN_KILLER_DQ3:
620 case PATTERN_KILLER_DQ4:
621 case PATTERN_KILLER_DQ5:
622 case PATTERN_KILLER_DQ6:
623 case PATTERN_KILLER_DQ7:
624 pattern = pattern_table_get_killer_word16(
625 (u8)(type - PATTERN_KILLER_DQ0), index);
626 break;
627 case PATTERN_RL2:
628 if (index < 3)
629 pattern = PATTERN_00;
630 else
631 pattern = PATTERN_01;
632 break;
633 case PATTERN_TEST:
634 pattern = PATTERN_0080;
635 break;
636 case PATTERN_FULL_SSO0:
637 pattern = 0x0000ffff;
638 break;
639 case PATTERN_FULL_SSO1:
640 case PATTERN_FULL_SSO2:
641 case PATTERN_FULL_SSO3:
642 pattern = pattern_table_get_sso_word(
643 (u8)(type - PATTERN_FULL_SSO1), index);
644 break;
645 case PATTERN_VREF:
646 pattern = pattern_table_get_vref_word16(index);
647 break;
648 default:
649 pattern = 0;
650 break;
651 }
652 }
653
654 return pattern;
655}