1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) Marvell International Ltd. and its affiliates
8 /* Device attributes structures */
9 enum mv_ddr_dev_attribute ddr_dev_attributes[MAX_DEVICE_NUM][MV_ATTR_LAST];
10 int ddr_dev_attr_init_done[MAX_DEVICE_NUM] = { 0 };
12 static inline u32 pattern_table_get_killer_word16(u8 dqs, u8 index);
13 static inline u32 pattern_table_get_sso_word(u8 sso, u8 index);
14 static inline u32 pattern_table_get_vref_word(u8 index);
15 static inline u32 pattern_table_get_vref_word16(u8 index);
16 static inline u32 pattern_table_get_sso_full_xtalk_word(u8 bit, u8 index);
17 static inline u32 pattern_table_get_sso_full_xtalk_word16(u8 bit, u8 index);
18 static inline u32 pattern_table_get_sso_xtalk_free_word(u8 bit, u8 index);
19 static inline u32 pattern_table_get_sso_xtalk_free_word16(u8 bit, u8 index);
20 static inline u32 pattern_table_get_isi_word(u8 index);
21 static inline u32 pattern_table_get_isi_word16(u8 index);
23 /* List of allowed frequency listed in order of enum hws_ddr_freq */
24 u32 freq_val[DDR_FREQ_LAST] = {
25 0, /*DDR_FREQ_LOW_FREQ */
26 400, /*DDR_FREQ_400, */
27 533, /*DDR_FREQ_533, */
28 666, /*DDR_FREQ_667, */
29 800, /*DDR_FREQ_800, */
30 933, /*DDR_FREQ_933, */
31 1066, /*DDR_FREQ_1066, */
32 311, /*DDR_FREQ_311, */
33 333, /*DDR_FREQ_333, */
34 467, /*DDR_FREQ_467, */
35 850, /*DDR_FREQ_850, */
36 600, /*DDR_FREQ_600 */
37 300, /*DDR_FREQ_300 */
38 900, /*DDR_FREQ_900 */
39 360, /*DDR_FREQ_360 */
40 1000 /*DDR_FREQ_1000 */
43 /* Table for CL values per frequency for each speed bin index */
44 struct cl_val_per_freq cas_latency_table[] = {
46 * 400M 667M 933M 311M 467M 600M 360
47 * 100M 533M 800M 1066M 333M 850M 900
48 * 1000 (the order is 100, 400, 533 etc.)
51 { {6, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
53 { {6, 6, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 6, 0, 6, 0} },
55 { {6, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 0, 5, 0, 5, 0} },
57 { {6, 6, 7, 0, 0, 0, 0, 6, 6, 7, 0, 0, 6, 0, 6, 0} },
59 { {6, 6, 8, 0, 0, 0, 0, 6, 6, 8, 0, 0, 6, 0, 6, 0} },
61 { {6, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
63 { {6, 5, 7, 8, 0, 0, 0, 5, 5, 7, 0, 8, 5, 0, 5, 0} },
65 { {6, 6, 8, 9, 0, 0, 0, 6, 6, 8, 0, 9, 6, 0, 6, 0} },
67 { {6, 6, 8, 10, 0, 0, 0, 6, 6, 8, 0, 10, 6, 0, 6, 0}
69 { {6, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
71 { {6, 5, 6, 8, 9, 0, 0, 5, 5, 6, 0, 8, 5, 0, 5, 0} },
73 { {6, 5, 7, 9, 10, 0, 0, 5, 5, 7, 0, 9, 5, 0, 5, 0} },
75 { {6, 6, 8, 10, 11, 0, 0, 6, 6, 8, 0, 10, 6, 0, 6, 0 } },
77 { {6, 5, 6, 8, 9, 11, 0, 5, 5, 6, 11, 8, 5, 0, 5, 0} },
79 { {6, 5, 7, 8, 10, 11, 0, 5, 5, 7, 11, 8, 5, 11, 5, 11} },
81 { {6, 6, 7, 9, 11, 12, 0, 6, 6, 7, 12, 9, 6, 12, 6, 12} },
83 { {6, 6, 8, 10, 11, 13, 0, 6, 6, 8, 13, 10, 6, 13, 6, 13} },
85 { {6, 5, 6, 7, 9, 10, 11, 5, 5, 6, 10, 7, 5, 11, 5, 11} },
87 { {6, 5, 6, 8, 9, 11, 12, 5, 5, 6, 11, 8, 5, 12, 5, 12} },
89 { {6, 5, 7, 9, 10, 12, 13, 5, 5, 7, 12, 9, 5, 13, 5, 13} },
91 { {6, 6, 7, 9, 11, 13, 14, 6, 6, 7, 13, 9, 6, 14, 6, 14} },
93 { {6, 6, 7, 9, 0, 0, 0, 6, 6, 7, 0, 9, 6, 0, 6, 0} },
95 { {6, 6, 7, 9, 11, 0, 0, 6, 6, 7, 0, 9, 6, 0, 6, 0} },
97 { {6, 6, 7, 9, 11, 13, 0, 6, 6, 7, 13, 9, 6, 13, 6, 13} },
100 /* Table for CWL values per speedbin index */
101 struct cl_val_per_freq cas_write_latency_table[] = {
103 * 400M 667M 933M 311M 467M 600M 360
104 * 100M 533M 800M 1066M 333M 850M 900
105 * (the order is 100, 400, 533 etc.)
108 { {5, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
110 { {5, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
112 { {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
114 { {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
116 { {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
118 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
120 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
122 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
124 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
126 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
128 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
130 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
132 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
134 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 0, 5, 0} },
136 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 0, 5, 0} },
138 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
140 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
142 { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
144 { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
146 { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
148 { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
150 { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
152 { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
154 { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
157 u8 twr_mask_table[] = {
177 u8 cl_mask_table[] = {
196 u8 cwl_mask_table[] = {
215 /* RFC values (in ns) */
222 0, /* TODO: placeholder for 16-Mbit dev width */
223 0, /* TODO: placeholder for 32-Mbit dev width */
224 0, /* TODO: placeholder for 12-Mbit dev width */
225 0 /* TODO: placeholder for 24-Mbit dev width */
228 u32 speed_bin_table_t_rc[] = {
252 u32 speed_bin_table_t_rcd_t_rp[] = {
277 PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR = 0,
278 PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM
281 static u8 pattern_killer_pattern_table_map[KILLER_PATTERN_LENGTH * 2][2] = {
282 /*Aggressor / Victim */
349 static u8 pattern_vref_pattern_table_map[] = {
350 /* 1 means 0xffffffff, 0 is 0x0 */
361 /* Return speed Bin value for selected index and t* element */
362 u32 speed_bin_table(u8 index, enum speed_bin_table_elements element)
369 result = speed_bin_table_t_rcd_t_rp[index];
372 if (index < SPEED_BIN_DDR_1066G)
374 else if (index < SPEED_BIN_DDR_1333J)
376 else if (index < SPEED_BIN_DDR_1600K)
378 else if (index < SPEED_BIN_DDR_1866M)
384 result = speed_bin_table_t_rc[index];
386 case SPEED_BIN_TRRD1K:
387 if (index < SPEED_BIN_DDR_800E)
389 else if (index < SPEED_BIN_DDR_1066G)
391 else if (index < SPEED_BIN_DDR_1600K)
396 case SPEED_BIN_TRRD2K:
397 if (index < SPEED_BIN_DDR_1066G)
399 else if (index < SPEED_BIN_DDR_1600K)
405 if (index < SPEED_BIN_DDR_800E)
407 else if (index < SPEED_BIN_DDR_1333J)
412 case SPEED_BIN_TFAW1K:
413 if (index < SPEED_BIN_DDR_800E)
415 else if (index < SPEED_BIN_DDR_1066G)
417 else if (index < SPEED_BIN_DDR_1600K)
419 else if (index < SPEED_BIN_DDR_1866M)
424 case SPEED_BIN_TFAW2K:
425 if (index < SPEED_BIN_DDR_1066G)
427 else if (index < SPEED_BIN_DDR_1333J)
429 else if (index < SPEED_BIN_DDR_1600K)
446 case SPEED_BIN_TXPDLL:
456 static inline u32 pattern_table_get_killer_word(u8 dqs, u8 index)
461 for (i = 0; i < 8; i++) {
463 (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) :
464 (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM);
465 byte |= pattern_killer_pattern_table_map[index][role] << i;
468 return byte | (byte << 8) | (byte << 16) | (byte << 24);
471 static inline u32 pattern_table_get_killer_word16(u8 dqs, u8 index)
473 u8 i, byte0 = 0, byte1 = 0;
476 for (i = 0; i < 8; i++) {
478 (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) :
479 (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM);
480 byte0 |= pattern_killer_pattern_table_map[index * 2][role] << i;
481 byte1 |= pattern_killer_pattern_table_map[index * 2 + 1][role] << i;
484 return byte0 | (byte0 << 8) | (byte1 << 16) | (byte1 << 24);
487 static inline u32 pattern_table_get_sso_word(u8 sso, u8 index)
491 if (0 == ((index / step) & 1))
497 static inline u32 pattern_table_get_sso_full_xtalk_word(u8 bit, u8 index)
499 u8 byte = (1 << bit);
501 if ((index & 1) == 1)
504 return byte | (byte << 8) | (byte << 16) | (byte << 24);
508 static inline u32 pattern_table_get_sso_xtalk_free_word(u8 bit, u8 index)
510 u8 byte = (1 << bit);
512 if ((index & 1) == 1)
515 return byte | (byte << 8) | (byte << 16) | (byte << 24);
518 static inline u32 pattern_table_get_isi_word(u8 index)
525 word = ((i1 == 5) | (i1 == 7)) ? 0xffffffff : 0x0;
527 word = (i1 == 6) ? 0xffffffff : 0x0;
529 word = ((i0 % 16) > 7) ? ~word : word;
534 static inline u32 pattern_table_get_sso_full_xtalk_word16(u8 bit, u8 index)
536 u8 byte = (1 << bit);
538 if ((index & 1) == 1)
541 return byte | (byte << 8) | ((~byte) << 16) | ((~byte) << 24);
544 static inline u32 pattern_table_get_sso_xtalk_free_word16(u8 bit, u8 index)
546 u8 byte = (1 << bit);
548 if ((index & 1) == 0)
549 return (byte << 16) | (byte << 24);
551 return byte | (byte << 8);
554 static inline u32 pattern_table_get_isi_word16(u8 index)
561 word = (i1 > 1) ? 0x0000ffff : 0x0;
563 word = (i1 == 3) ? 0xffff0000 : 0x0;
565 word = ((i0 % 8) > 3) ? ~word : word;
570 static inline u32 pattern_table_get_vref_word(u8 index)
572 if (0 == ((pattern_vref_pattern_table_map[index / 8] >>
579 static inline u32 pattern_table_get_vref_word16(u8 index)
581 if (0 == pattern_killer_pattern_table_map
582 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] &&
583 0 == pattern_killer_pattern_table_map
584 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1])
586 else if (1 == pattern_killer_pattern_table_map
587 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] &&
588 0 == pattern_killer_pattern_table_map
589 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1])
591 else if (0 == pattern_killer_pattern_table_map
592 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] &&
593 1 == pattern_killer_pattern_table_map
594 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1])
600 static inline u32 pattern_table_get_static_pbs_word(u8 index)
604 temp = ((0x00ff << (index / 3)) & 0xff00) >> 8;
606 return temp | (temp << 8) | (temp << 16) | (temp << 24);
609 u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
612 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
614 if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask) == 0) {
615 /* 32/64-bit patterns */
619 if (index == 0 || index == 2 || index == 5 ||
621 pattern = PATTERN_55;
623 pattern = PATTERN_AA;
626 if (0 == (index & 1))
627 pattern = PATTERN_55;
629 pattern = PATTERN_AA;
633 pattern = PATTERN_00;
635 pattern = PATTERN_80;
637 case PATTERN_STATIC_PBS:
638 pattern = pattern_table_get_static_pbs_word(index);
640 case PATTERN_KILLER_DQ0:
641 case PATTERN_KILLER_DQ1:
642 case PATTERN_KILLER_DQ2:
643 case PATTERN_KILLER_DQ3:
644 case PATTERN_KILLER_DQ4:
645 case PATTERN_KILLER_DQ5:
646 case PATTERN_KILLER_DQ6:
647 case PATTERN_KILLER_DQ7:
648 pattern = pattern_table_get_killer_word(
649 (u8)(type - PATTERN_KILLER_DQ0), index);
653 pattern = PATTERN_00;
655 pattern = PATTERN_01;
658 if (index > 1 && index < 6)
659 pattern = PATTERN_00;
661 pattern = PATTERN_FF;
663 case PATTERN_FULL_SSO0:
664 case PATTERN_FULL_SSO1:
665 case PATTERN_FULL_SSO2:
666 case PATTERN_FULL_SSO3:
667 pattern = pattern_table_get_sso_word(
668 (u8)(type - PATTERN_FULL_SSO0), index);
671 pattern = pattern_table_get_vref_word(index);
673 case PATTERN_SSO_FULL_XTALK_DQ0:
674 case PATTERN_SSO_FULL_XTALK_DQ1:
675 case PATTERN_SSO_FULL_XTALK_DQ2:
676 case PATTERN_SSO_FULL_XTALK_DQ3:
677 case PATTERN_SSO_FULL_XTALK_DQ4:
678 case PATTERN_SSO_FULL_XTALK_DQ5:
679 case PATTERN_SSO_FULL_XTALK_DQ6:
680 case PATTERN_SSO_FULL_XTALK_DQ7:
681 pattern = pattern_table_get_sso_full_xtalk_word(
682 (u8)(type - PATTERN_SSO_FULL_XTALK_DQ0), index);
684 case PATTERN_SSO_XTALK_FREE_DQ0:
685 case PATTERN_SSO_XTALK_FREE_DQ1:
686 case PATTERN_SSO_XTALK_FREE_DQ2:
687 case PATTERN_SSO_XTALK_FREE_DQ3:
688 case PATTERN_SSO_XTALK_FREE_DQ4:
689 case PATTERN_SSO_XTALK_FREE_DQ5:
690 case PATTERN_SSO_XTALK_FREE_DQ6:
691 case PATTERN_SSO_XTALK_FREE_DQ7:
692 pattern = pattern_table_get_sso_xtalk_free_word(
693 (u8)(type - PATTERN_SSO_XTALK_FREE_DQ0), index);
695 case PATTERN_ISI_XTALK_FREE:
696 pattern = pattern_table_get_isi_word(index);
699 DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("Error: %s: pattern type [%d] not supported\n",
700 __func__, (int)type));
710 pattern = PATTERN_55AA;
714 pattern = PATTERN_00;
716 pattern = PATTERN_80;
718 case PATTERN_STATIC_PBS:
719 pattern = PATTERN_00FF;
721 case PATTERN_KILLER_DQ0:
722 case PATTERN_KILLER_DQ1:
723 case PATTERN_KILLER_DQ2:
724 case PATTERN_KILLER_DQ3:
725 case PATTERN_KILLER_DQ4:
726 case PATTERN_KILLER_DQ5:
727 case PATTERN_KILLER_DQ6:
728 case PATTERN_KILLER_DQ7:
729 pattern = pattern_table_get_killer_word16(
730 (u8)(type - PATTERN_KILLER_DQ0), index);
734 pattern = PATTERN_00;
736 pattern = PATTERN_01;
739 if ((index == 0) || (index == 3))
740 pattern = 0x00000000;
742 pattern = 0xFFFFFFFF;
744 case PATTERN_FULL_SSO0:
745 pattern = 0x0000ffff;
747 case PATTERN_FULL_SSO1:
748 case PATTERN_FULL_SSO2:
749 case PATTERN_FULL_SSO3:
750 pattern = pattern_table_get_sso_word(
751 (u8)(type - PATTERN_FULL_SSO1), index);
754 pattern = pattern_table_get_vref_word16(index);
756 case PATTERN_SSO_FULL_XTALK_DQ0:
757 case PATTERN_SSO_FULL_XTALK_DQ1:
758 case PATTERN_SSO_FULL_XTALK_DQ2:
759 case PATTERN_SSO_FULL_XTALK_DQ3:
760 case PATTERN_SSO_FULL_XTALK_DQ4:
761 case PATTERN_SSO_FULL_XTALK_DQ5:
762 case PATTERN_SSO_FULL_XTALK_DQ6:
763 case PATTERN_SSO_FULL_XTALK_DQ7:
764 pattern = pattern_table_get_sso_full_xtalk_word16(
765 (u8)(type - PATTERN_SSO_FULL_XTALK_DQ0), index);
767 case PATTERN_SSO_XTALK_FREE_DQ0:
768 case PATTERN_SSO_XTALK_FREE_DQ1:
769 case PATTERN_SSO_XTALK_FREE_DQ2:
770 case PATTERN_SSO_XTALK_FREE_DQ3:
771 case PATTERN_SSO_XTALK_FREE_DQ4:
772 case PATTERN_SSO_XTALK_FREE_DQ5:
773 case PATTERN_SSO_XTALK_FREE_DQ6:
774 case PATTERN_SSO_XTALK_FREE_DQ7:
775 pattern = pattern_table_get_sso_xtalk_free_word16(
776 (u8)(type - PATTERN_SSO_XTALK_FREE_DQ0), index);
778 case PATTERN_ISI_XTALK_FREE:
779 pattern = pattern_table_get_isi_word16(index);
782 DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("Error: %s: pattern type [%d] not supported\n",
783 __func__, (int)type));
792 /* Device attribute functions */
793 void ddr3_tip_dev_attr_init(u32 dev_num)
797 for (attr_id = 0; attr_id < MV_ATTR_LAST; attr_id++)
798 ddr_dev_attributes[dev_num][attr_id] = 0xFF;
800 ddr_dev_attr_init_done[dev_num] = 1;
803 u32 ddr3_tip_dev_attr_get(u32 dev_num, enum mv_ddr_dev_attribute attr_id)
805 if (ddr_dev_attr_init_done[dev_num] == 0)
806 ddr3_tip_dev_attr_init(dev_num);
808 return ddr_dev_attributes[dev_num][attr_id];
811 void ddr3_tip_dev_attr_set(u32 dev_num, enum mv_ddr_dev_attribute attr_id, u32 value)
813 if (ddr_dev_attr_init_done[dev_num] == 0)
814 ddr3_tip_dev_attr_init(dev_num);
816 ddr_dev_attributes[dev_num][attr_id] = value;