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>
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_db.c b/drivers/ddr/marvell/a38x/ddr3_training_db.c
index 6aa7b60..47ba911 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_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 @@
 	12155,
 	13090,
 };
+#endif /* CONFIG_DDR4 */
 
 enum {
 	PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR = 0,
@@ -388,6 +481,7 @@
 	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 @@
 
 	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 @@
 		return 0xffffffff;
 }
 
+#if !defined(CONFIG_DDR4)
 static inline u32 pattern_table_get_static_pbs_word(u8 index)
 {
 	u16 temp;
@@ -659,6 +755,7 @@
 
 	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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 				(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 @@
 		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;