summaryrefslogtreecommitdiff
path: root/drivers/ddr/marvell/a38x/ddr3_training_db.c
diff options
context:
space:
mode:
authorTony Dinh <mibodhi@gmail.com>2023-01-18 19:03:04 -0800
committerStefan Roese <sr@denx.de>2023-01-26 07:30:20 +0100
commit54a08c4139e6677494d62c7cb595d70ef123a86b (patch)
tree1e5ee0e5183844df43a8d968e61aa2487a9856e2 /drivers/ddr/marvell/a38x/ddr3_training_db.c
parent17e8e58fe62c019b2cc26af221b6defc3368229f (diff)
ddr: marvell: a38x: Add support for DDR4 from Marvell mv-ddr-marvell repository
This syncs drivers/ddr/marvell/a38x/ with the master branch of repository https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git up to the commit "mv_ddr: a3700: Use the right size for memset to not overflow" d5acc10c287e40cc2feeb28710b92e45c93c702c This patch was created by following steps: 1. Replace all a38x files in U-Boot tree by files from upstream github Marvell mv-ddr-marvell repository. 2. Run following command to omit portions not relevant for a38x, ddr3, and ddr4: files=drivers/ddr/marvell/a38x/* unifdef -m -UMV_DDR -UMV_DDR_ATF -UCONFIG_APN806 \ -UCONFIG_MC_STATIC -UCONFIG_MC_STATIC_PRINT -UCONFIG_PHY_STATIC \ -UCONFIG_PHY_STATIC_PRINT -UCONFIG_CUSTOMER_BOARD_SUPPORT \ -UCONFIG_A3700 -UA3900 -UA80X0 -UA70X0 -DCONFIG_ARMADA_38X -UCONFIG_ARMADA_39X \ -UCONFIG_64BIT $files 3. Manually change license to SPDX-License-Identifier (upstream license in upstream github repository contains long license texts and U-Boot is using just SPDX-License-Identifier. After applying this patch, a38x, ddr3, and ddr4 code in upstream Marvell github repository and in U-Boot would be fully identical. So in future applying above steps could be used to sync code again. The only change in this patch are: 1. Some fixes with include files. 2. Some function return and basic type defines changes in mv_ddr_plat.c (to correct Marvell bug). 3. Remove of dead code in newly copied files (as a result of the filter script stripping out everything other than a38x, dd3, and ddr4). Reference: "ddr: marvell: a38x: Sync code with Marvell mv-ddr-marvell repository" https://source.denx.de/u-boot/u-boot/-/commit/107c3391b95bcc2ba09a876da4fa0c31b6c1e460 Signed-off-by: Tony Dinh <mibodhi@gmail.com> Reviewed-by: Pali Rohár <pali@kernel.org> Reviewed-by: Stefan Roese <sr@denx.de>
Diffstat (limited to 'drivers/ddr/marvell/a38x/ddr3_training_db.c')
-rw-r--r--drivers/ddr/marvell/a38x/ddr3_training_db.c212
1 files changed, 212 insertions, 0 deletions
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_db.c b/drivers/ddr/marvell/a38x/ddr3_training_db.c
index 6aa7b6069e8..47ba911e0df 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training_db.c
+++ b/drivers/ddr/marvell/a38x/ddr3_training_db.c
@@ -25,6 +25,98 @@ static inline u32 pattern_table_get_sso_xtalk_free_word16(u8 bit, u8 index);
static inline u32 pattern_table_get_isi_word(u8 index);
static inline u32 pattern_table_get_isi_word16(u8 index);
+#if defined(CONFIG_DDR4)
+u8 pattern_killer_map[KILLER_PATTERN_LENGTH * 2] = {
+ 0x01,
+ 0x00,
+ 0x01,
+ 0xff,
+ 0xfe,
+ 0xfe,
+ 0x01,
+ 0xfe,
+ 0x01,
+ 0xfe,
+ 0x01,
+ 0x01,
+ 0xfe,
+ 0x01,
+ 0xfe,
+ 0x00,
+ 0xff,
+ 0x00,
+ 0xff,
+ 0x00,
+ 0xff,
+ 0x00,
+ 0xff,
+ 0x01,
+ 0x00,
+ 0xff,
+ 0x00,
+ 0xff,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xfe,
+ 0xfe,
+ 0xff,
+ 0x00,
+ 0x00,
+ 0xff,
+ 0xff,
+ 0x00,
+ 0xff,
+ 0x00,
+ 0xff,
+ 0xff,
+ 0x00,
+ 0x00,
+ 0xff,
+ 0x00,
+ 0xff,
+ 0xfe,
+ 0x00,
+ 0xfe,
+ 0xfe,
+ 0x00,
+ 0xff,
+ 0xff,
+ 0x01,
+ 0x01,
+ 0xff,
+ 0xff,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0xff
+};
+static inline u32 pattern_table_get_killer_word_4(u8 dqs, u8 index)
+{
+ u8 byte;
+
+ if (index >= (KILLER_PATTERN_LENGTH * 2)) {
+ printf("error: %s: invalid index [%u] found\n", __func__, index);
+ return 0;
+ }
+
+ byte = pattern_killer_map[index];
+
+ switch (byte) {
+ case 0x01:
+ byte = 1 << dqs;
+ break;
+ case 0xfe:
+ byte = 0xff & ~(1 << dqs);
+ break;
+ default:
+ break;
+ }
+
+ return byte | (byte << 8) | (byte << 16) | (byte << 24);
+}
+#else /* !CONFIG_DDR4 */
/* List of allowed frequency listed in order of enum mv_ddr_freq */
static unsigned int freq_val[MV_DDR_FREQ_LAST] = {
0, /*MV_DDR_FREQ_LOW_FREQ */
@@ -302,6 +394,7 @@ u32 speed_bin_table_t_rcd_t_rp[] = {
12155,
13090,
};
+#endif /* CONFIG_DDR4 */
enum {
PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR = 0,
@@ -388,6 +481,7 @@ static u8 pattern_vref_pattern_table_map[] = {
0xfe
};
+#if !defined(CONFIG_DDR4)
static struct mv_ddr_page_element page_tbl[] = {
/* 8-bit, 16-bit page size */
{MV_DDR_PAGE_SIZE_1K, MV_DDR_PAGE_SIZE_2K}, /* 512M */
@@ -521,6 +615,7 @@ static inline u32 pattern_table_get_killer_word(u8 dqs, u8 index)
return byte | (byte << 8) | (byte << 16) | (byte << 24);
}
+#endif /* !CONFIG_DDR4 */
static inline u32 pattern_table_get_killer_word16(u8 dqs, u8 index)
{
@@ -651,6 +746,7 @@ static inline u32 pattern_table_get_vref_word16(u8 index)
return 0xffffffff;
}
+#if !defined(CONFIG_DDR4)
static inline u32 pattern_table_get_static_pbs_word(u8 index)
{
u16 temp;
@@ -659,6 +755,7 @@ static inline u32 pattern_table_get_static_pbs_word(u8 index)
return temp | (temp << 8) | (temp << 16) | (temp << 24);
}
+#endif /* !CONFIG_DDR4 */
u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
{
@@ -670,26 +767,36 @@ u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
switch (type) {
case PATTERN_PBS1:
case PATTERN_PBS2:
+#if !defined(CONFIG_DDR4)
if (index == 0 || index == 2 || index == 5 ||
index == 7)
pattern = PATTERN_55;
else
pattern = PATTERN_AA;
break;
+#endif /* !CONFIG_DDR4 */
case PATTERN_PBS3:
+#if !defined(CONFIG_DDR4)
if (0 == (index & 1))
pattern = PATTERN_55;
else
pattern = PATTERN_AA;
+#endif /* !CONFIG_DDR4 */
break;
case PATTERN_RL:
+#if !defined(CONFIG_DDR4)
if (index < 6)
pattern = PATTERN_00;
else
pattern = PATTERN_80;
+#else /* CONFIG_DDR4 */
+ pattern = PATTERN_00;
+#endif /* !CONFIG_DDR4 */
break;
case PATTERN_STATIC_PBS:
+#if !defined(CONFIG_DDR4)
pattern = pattern_table_get_static_pbs_word(index);
+#endif /* !CONFIG_DDR4 */
break;
case PATTERN_KILLER_DQ0:
case PATTERN_KILLER_DQ1:
@@ -699,14 +806,22 @@ u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
case PATTERN_KILLER_DQ5:
case PATTERN_KILLER_DQ6:
case PATTERN_KILLER_DQ7:
+#if !defined(CONFIG_DDR4)
pattern = pattern_table_get_killer_word(
+#else /* CONFIG_DDR4 */
+ pattern = pattern_table_get_killer_word_4(
+#endif /* !CONFIG_DDR4 */
(u8)(type - PATTERN_KILLER_DQ0), index);
break;
case PATTERN_RL2:
+#if !defined(CONFIG_DDR4)
if (index < 6)
pattern = PATTERN_00;
else
pattern = PATTERN_01;
+#else /* !CONFIG_DDR4 */
+ pattern = PATTERN_FF;
+#endif /* CONFIG_DDR4 */
break;
case PATTERN_TEST:
if (index > 1 && index < 6)
@@ -749,6 +864,46 @@ u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
case PATTERN_ISI_XTALK_FREE:
pattern = pattern_table_get_isi_word(index);
break;
+#if defined(CONFIG_DDR4)
+ case PATTERN_KILLER_DQ0_INV:
+ case PATTERN_KILLER_DQ1_INV:
+ case PATTERN_KILLER_DQ2_INV:
+ case PATTERN_KILLER_DQ3_INV:
+ case PATTERN_KILLER_DQ4_INV:
+ case PATTERN_KILLER_DQ5_INV:
+ case PATTERN_KILLER_DQ6_INV:
+ case PATTERN_KILLER_DQ7_INV:
+ pattern = ~pattern_table_get_killer_word_4(
+ (u8)(type - PATTERN_KILLER_DQ0_INV), index);
+ break;
+ case PATTERN_RESONANCE_1T:
+ case PATTERN_RESONANCE_2T:
+ case PATTERN_RESONANCE_3T:
+ case PATTERN_RESONANCE_4T:
+ case PATTERN_RESONANCE_5T:
+ case PATTERN_RESONANCE_6T:
+ case PATTERN_RESONANCE_7T:
+ case PATTERN_RESONANCE_8T:
+ case PATTERN_RESONANCE_9T:
+ {
+ u8 t_num = (u8)(type - PATTERN_RESONANCE_1T);
+ u8 t_end = (59 / t_num) * t_num;
+ if (index < t_end)
+ pattern = ((index % (t_num * 2)) >= t_num) ? 0xffffffff : 0x00000000;
+ else
+ pattern = ((index % 2) == 0) ? 0xffffffff : 0x00000000;
+ }
+ break;
+ case PATTERN_ZERO:
+ pattern = PATTERN_00;
+ break;
+ case PATTERN_ONE:
+ pattern = PATTERN_FF;
+ break;
+ case PATTERN_VREF_INV:
+ pattern = ~pattern_table_get_vref_word(index);
+ break;
+#endif /* CONFIG_DDR4 */
default:
printf("error: %s: unsupported pattern type [%d] found\n",
__func__, (int)type);
@@ -761,16 +916,24 @@ u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
case PATTERN_PBS1:
case PATTERN_PBS2:
case PATTERN_PBS3:
+#if !defined(CONFIG_DDR4)
pattern = PATTERN_55AA;
+#endif /* !CONFIG_DDR4 */
break;
case PATTERN_RL:
+#if !defined(CONFIG_DDR4)
if (index < 3)
pattern = PATTERN_00;
else
pattern = PATTERN_80;
+#else /* CONFIG_DDR4 */
+ pattern = PATTERN_00;
+#endif /* !CONFIG_DDR4 */
break;
case PATTERN_STATIC_PBS:
+#if !defined(CONFIG_DDR4)
pattern = PATTERN_00FF;
+#endif /* !CONFIG_DDR4 */
break;
case PATTERN_KILLER_DQ0:
case PATTERN_KILLER_DQ1:
@@ -784,25 +947,40 @@ u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
(u8)(type - PATTERN_KILLER_DQ0), index);
break;
case PATTERN_RL2:
+#if !defined(CONFIG_DDR4)
if (index < 3)
pattern = PATTERN_00;
else
pattern = PATTERN_01;
+#endif /* !CONFIG_DDR4 */
break;
case PATTERN_TEST:
+#if !defined(CONFIG_DDR4)
if ((index == 0) || (index == 3))
pattern = 0x00000000;
else
pattern = 0xFFFFFFFF;
+#else /* CONFIG_DDR4 */
+ if ((index > 1) && (index < 6))
+ pattern = PATTERN_20;
+ else
+ pattern = PATTERN_00;
+#endif /* !CONFIG_DDR4 */
break;
case PATTERN_FULL_SSO0:
+#if !defined(CONFIG_DDR4)
pattern = 0x0000ffff;
break;
+#endif /* !CONFIG_DDR4 */
case PATTERN_FULL_SSO1:
case PATTERN_FULL_SSO2:
case PATTERN_FULL_SSO3:
pattern = pattern_table_get_sso_word(
+#if !defined(CONFIG_DDR4)
(u8)(type - PATTERN_FULL_SSO1), index);
+#else /* CONFIG_DDR4 */
+ (u8)(type - PATTERN_FULL_SSO0), index);
+#endif /* !CONFIG_DDR4 */
break;
case PATTERN_VREF:
pattern = pattern_table_get_vref_word16(index);
@@ -832,6 +1010,40 @@ u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
case PATTERN_ISI_XTALK_FREE:
pattern = pattern_table_get_isi_word16(index);
break;
+#if defined(CONFIG_DDR4)
+ case PATTERN_KILLER_DQ0_INV:
+ case PATTERN_KILLER_DQ1_INV:
+ case PATTERN_KILLER_DQ2_INV:
+ case PATTERN_KILLER_DQ3_INV:
+ case PATTERN_KILLER_DQ4_INV:
+ case PATTERN_KILLER_DQ5_INV:
+ case PATTERN_KILLER_DQ6_INV:
+ case PATTERN_KILLER_DQ7_INV:
+ pattern = ~pattern_table_get_killer_word16(
+ (u8)(type - PATTERN_KILLER_DQ0_INV), index);
+ break;
+ case PATTERN_RESONANCE_1T:
+ case PATTERN_RESONANCE_2T:
+ case PATTERN_RESONANCE_3T:
+ case PATTERN_RESONANCE_4T:
+ case PATTERN_RESONANCE_5T:
+ case PATTERN_RESONANCE_6T:
+ case PATTERN_RESONANCE_7T:
+ case PATTERN_RESONANCE_8T:
+ case PATTERN_RESONANCE_9T:
+ {
+ u8 t_num = (u8)(type - PATTERN_RESONANCE_1T);
+ u8 t_end = (59 / t_num) * t_num;
+ if (index < t_end)
+ pattern = ((index % (t_num * 2)) >= t_num) ? 0xffffffff : 0x00000000;
+ else
+ pattern = ((index % 2) == 0) ? 0xffffffff : 0x00000000;
+ }
+ break;
+ case PATTERN_VREF_INV:
+ pattern = ~pattern_table_get_vref_word16(index);
+ break;
+#endif /* CONFIG_DDR4 */
default:
if (((int)type == 29) || ((int)type == 30))
break;