From 54a08c4139e6677494d62c7cb595d70ef123a86b Mon Sep 17 00:00:00 2001 From: Tony Dinh Date: Wed, 18 Jan 2023 19:03:04 -0800 Subject: ddr: marvell: a38x: Add support for DDR4 from Marvell mv-ddr-marvell repository MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Pali Rohár Reviewed-by: Stefan Roese --- drivers/ddr/marvell/a38x/ddr3_training_db.c | 212 ++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) (limited to 'drivers/ddr/marvell/a38x/ddr3_training_db.c') 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; -- cgit v1.2.3