2 * Copyright (C) Marvell International Ltd. and its affiliates
4 * SPDX-License-Identifier: GPL-2.0
10 #include <asm/arch/cpu.h>
11 #include <asm/arch/soc.h>
13 #include "ddr3_init.h"
15 /* List of allowed frequency listed in order of enum hws_ddr_freq */
16 u32 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 */
35 /* Table for CL values per frequency for each speed bin index */
36 struct cl_val_per_freq cas_latency_table[] = {
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.)
43 { {6, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
45 { {6, 6, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 6, 0, 6, 0} },
47 { {6, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 0, 5, 0, 5, 0} },
49 { {6, 6, 7, 0, 0, 0, 0, 6, 6, 7, 0, 0, 6, 0, 6, 0} },
51 { {6, 6, 8, 0, 0, 0, 0, 6, 6, 8, 0, 0, 6, 0, 6, 0} },
53 { {6, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
55 { {6, 5, 7, 8, 0, 0, 0, 5, 5, 7, 0, 8, 5, 0, 5, 0} },
57 { {6, 6, 8, 9, 0, 0, 0, 6, 6, 8, 0, 9, 6, 0, 6, 0} },
59 { {6, 6, 8, 10, 0, 0, 0, 6, 6, 8, 0, 10, 6, 0, 6, 0}
61 { {6, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
63 { {6, 5, 6, 8, 9, 0, 0, 5, 5, 6, 0, 8, 5, 0, 5, 0} },
65 { {6, 5, 7, 9, 10, 0, 0, 5, 5, 7, 0, 9, 5, 0, 5, 0} },
67 { {6, 6, 8, 10, 11, 0, 0, 6, 6, 8, 0, 10, 6, 0, 6, 0 } },
69 { {6, 5, 6, 8, 9, 11, 0, 5, 5, 6, 11, 8, 5, 0, 5, 0} },
71 { {6, 5, 7, 8, 10, 11, 0, 5, 5, 7, 11, 8, 5, 11, 5, 11} },
73 { {6, 6, 7, 9, 11, 12, 0, 6, 6, 7, 12, 9, 6, 12, 6, 12} },
75 { {6, 6, 8, 10, 11, 13, 0, 6, 6, 8, 13, 10, 6, 13, 6, 13} },
77 { {6, 5, 6, 7, 9, 10, 11, 5, 5, 6, 10, 7, 5, 11, 5, 11} },
79 { {6, 5, 6, 8, 9, 11, 12, 5, 5, 6, 11, 8, 5, 12, 5, 12} },
81 { {6, 5, 7, 9, 10, 12, 13, 5, 5, 7, 12, 9, 5, 13, 5, 13} },
83 { {6, 6, 7, 9, 11, 13, 14, 6, 6, 7, 13, 9, 6, 14, 6, 14} },
85 { {6, 6, 7, 9, 0, 0, 0, 6, 6, 7, 0, 9, 6, 0, 6, 0} },
87 { {6, 6, 7, 9, 11, 0, 0, 6, 6, 7, 0, 9, 6, 0, 6, 0} },
89 { {6, 6, 7, 9, 11, 13, 0, 6, 6, 7, 13, 9, 6, 13, 6, 13} },
92 /* Table for CWL values per speedbin index */
93 struct cl_val_per_freq cas_write_latency_table[] = {
95 * 400M 667M 933M 311M 467M 600M 360
96 * 100M 533M 800M 1066M 333M 850M 900
97 * (the order is 100, 400, 533 etc.)
100 { {5, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
102 { {5, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
104 { {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
106 { {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
108 { {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
110 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
112 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
114 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
116 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
118 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
120 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
122 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
124 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
126 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 0, 5, 0} },
128 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 0, 5, 0} },
130 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
132 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
134 { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
136 { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
138 { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
140 { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
142 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
144 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
146 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
149 u8 twr_mask_table[] = {
169 u8 cl_mask_table[] = {
188 u8 cwl_mask_table[] = {
207 /* RFC values (in ns) */
216 u32 speed_bin_table_t_rc[] = {
240 u32 speed_bin_table_t_rcd_t_rp[] = {
265 PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR = 0,
266 PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM
269 static u8 pattern_killer_pattern_table_map[KILLER_PATTERN_LENGTH * 2][2] = {
270 /*Aggressor / Victim */
337 static u8 pattern_vref_pattern_table_map[] = {
338 /* 1 means 0xffffffff, 0 is 0x0 */
349 /* Return speed Bin value for selected index and t* element */
350 u32 speed_bin_table(u8 index, enum speed_bin_table_elements element)
357 result = speed_bin_table_t_rcd_t_rp[index];
372 result = speed_bin_table_t_rc[index];
374 case SPEED_BIN_TRRD1K:
384 case SPEED_BIN_TRRD2K:
400 case SPEED_BIN_TFAW1K:
412 case SPEED_BIN_TFAW2K:
434 case SPEED_BIN_TXPDLL:
444 static inline u32 pattern_table_get_killer_word(u8 dqs, u8 index)
449 for (i = 0; i < 8; i++) {
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;
456 return byte | (byte << 8) | (byte << 16) | (byte << 24);
459 static inline u32 pattern_table_get_killer_word16(u8 dqs, u8 index)
461 u8 i, byte0 = 0, byte1 = 0;
464 for (i = 0; i < 8; i++) {
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;
471 for (i = 0; i < 8; i++) {
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;
479 return byte0 | (byte0 << 8) | (byte1 << 16) | (byte1 << 24);
482 static inline u32 pattern_table_get_sso_word(u8 sso, u8 index)
486 if (0 == ((index / step) & 1))
492 static inline u32 pattern_table_get_vref_word(u8 index)
494 if (0 == ((pattern_vref_pattern_table_map[index / 8] >>
501 static inline u32 pattern_table_get_vref_word16(u8 index)
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])
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])
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])
522 static inline u32 pattern_table_get_static_pbs_word(u8 index)
526 temp = ((0x00ff << (index / 3)) & 0xff00) >> 8;
528 return temp | (temp << 8) | (temp << 16) | (temp << 24);
531 inline u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
534 struct hws_topology_map *tm = ddr3_get_topology_map();
536 if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask) == 0) {
541 if (index == 0 || index == 2 || index == 5 ||
543 pattern = PATTERN_55;
545 pattern = PATTERN_AA;
548 if (0 == (index & 1))
549 pattern = PATTERN_55;
551 pattern = PATTERN_AA;
555 pattern = PATTERN_00;
557 pattern = PATTERN_80;
559 case PATTERN_STATIC_PBS:
560 pattern = pattern_table_get_static_pbs_word(index);
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);
575 pattern = PATTERN_00;
577 pattern = PATTERN_01;
580 if (index > 1 && index < 6)
581 pattern = PATTERN_20;
583 pattern = PATTERN_00;
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);
593 pattern = pattern_table_get_vref_word(index);
605 pattern = PATTERN_55AA;
609 pattern = PATTERN_00;
611 pattern = PATTERN_80;
613 case PATTERN_STATIC_PBS:
614 pattern = PATTERN_00FF;
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);
629 pattern = PATTERN_00;
631 pattern = PATTERN_01;
634 pattern = PATTERN_0080;
636 case PATTERN_FULL_SSO0:
637 pattern = 0x0000ffff;
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);
646 pattern = pattern_table_get_vref_word16(index);