All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v2 0/6] ARM: mvebu: a38x: updates to ddr training code
@ 2018-04-09 10:12 Chris Packham
  2018-04-09 10:12 ` [U-Boot] [PATCH v2 1/6] ARM: mvebu: a38x: move definition of PEX_CFG_DIRECT_ACCESS Chris Packham
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Chris Packham @ 2018-04-09 10:12 UTC (permalink / raw)
  To: u-boot

This series updates the ddr training code in u-boot with the latest
publicly available version from Marvell which can be found at
https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git
(mv_ddr-armada-17.10 branch).

I've tried to make the delta as small as possible without breaking
bisect-ability.

The first 2 patches have already been sent as
http://patchwork.ozlabs.org/patch/894866/ and
http://patchwork.ozlabs.org/patch/894865/

The bulk of the changes are in patch 4. Naturally this doesn't pass
checkpatch.pl but I'm erring on the side of being able to diff with the
upstream source. Also due to it's size this patch may not make it to the
mailing list so the full series can be retrieved from the mv-ddr branch
of https://github.com/cpackham/u-boot.git.

I've tested this series on the db-88f6820-amc board and on a custom
board that is not upstream (yet). I've also build tested the other a38x
boards. More testing on actual hardware would be greatly appreciated.

Changes in v2:
- remove unused #include

Chris Packham (6):
  ARM: mvebu: a38x: move definition of PEX_CFG_DIRECT_ACCESS
  ARM: mvebu: a38x: move sys_env_device_rev_get
  ARM: mvebu: a38x: remove some unused code
  ARM: mvebu: a38x: sync ddr training code with upstream
  ARM: mvebu: a38x: restore support for setting timing
  ARM: mvebu: a38x: use non-zero size for ddr scrubbing

 arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h         |    1 +
 arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c      |   26 +-
 arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h      |    1 -
 board/CZ.NIC/turris_omnia/turris_omnia.c           |   38 +-
 board/Marvell/db-88f6820-amc/db-88f6820-amc.c      |   21 +-
 board/Marvell/db-88f6820-gp/db-88f6820-gp.c        |   21 +-
 board/gdsys/a38x/controlcenterdc.c                 |   22 +-
 board/solidrun/clearfog/clearfog.c                 |   21 +-
 drivers/ddr/marvell/a38x/Makefile                  |   10 +-
 drivers/ddr/marvell/a38x/ddr3_a38x.c               |  737 ----------
 drivers/ddr/marvell/a38x/ddr3_a38x.h               |   93 --
 drivers/ddr/marvell/a38x/ddr3_a38x_mc_static.h     |  226 ---
 drivers/ddr/marvell/a38x/ddr3_a38x_topology.h      |   22 -
 drivers/ddr/marvell/a38x/ddr3_a38x_training.c      |   40 -
 drivers/ddr/marvell/a38x/ddr3_debug.c              |  742 ++++++----
 drivers/ddr/marvell/a38x/ddr3_hws_hw_training.c    |  148 --
 drivers/ddr/marvell/a38x/ddr3_hws_hw_training.h    |   49 -
 .../ddr/marvell/a38x/ddr3_hws_hw_training_def.h    |  464 ------
 drivers/ddr/marvell/a38x/ddr3_hws_sil_training.h   |   17 -
 drivers/ddr/marvell/a38x/ddr3_init.c               |  798 ++---------
 drivers/ddr/marvell/a38x/ddr3_init.h               |  300 +---
 drivers/ddr/marvell/a38x/ddr3_logging_def.h        |   10 +-
 drivers/ddr/marvell/a38x/ddr3_patterns_64bit.h     |    1 +
 drivers/ddr/marvell/a38x/ddr3_topology_def.h       |    6 +-
 drivers/ddr/marvell/a38x/ddr3_training.c           | 1491 +++++++++++---------
 drivers/ddr/marvell/a38x/ddr3_training_bist.c      |  548 +++++--
 .../marvell/a38x/ddr3_training_centralization.c    |  108 +-
 drivers/ddr/marvell/a38x/ddr3_training_db.c        |  267 +++-
 drivers/ddr/marvell/a38x/ddr3_training_hw_algo.c   |   98 +-
 drivers/ddr/marvell/a38x/ddr3_training_ip.h        |   19 +-
 drivers/ddr/marvell/a38x/ddr3_training_ip_bist.h   |    6 +-
 drivers/ddr/marvell/a38x/ddr3_training_ip_db.h     |   71 +-
 drivers/ddr/marvell/a38x/ddr3_training_ip_def.h    |   34 +-
 drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c | 1134 +++++++++------
 drivers/ddr/marvell/a38x/ddr3_training_ip_engine.h |    9 +-
 drivers/ddr/marvell/a38x/ddr3_training_ip_flow.h   |  305 +---
 drivers/ddr/marvell/a38x/ddr3_training_ip_prv_if.h |   17 +-
 drivers/ddr/marvell/a38x/ddr3_training_ip_static.h |   31 -
 drivers/ddr/marvell/a38x/ddr3_training_leveling.c  | 1347 ++++++++++--------
 drivers/ddr/marvell/a38x/ddr3_training_leveling.h  |    2 +-
 drivers/ddr/marvell/a38x/ddr3_training_pbs.c       |  201 +--
 drivers/ddr/marvell/a38x/ddr3_training_static.c    |  539 -------
 drivers/ddr/marvell/a38x/ddr_ml_wrapper.h          |  149 ++
 drivers/ddr/marvell/a38x/ddr_topology_def.h        |   84 +-
 drivers/ddr/marvell/a38x/mv_ddr_build_message.c    |    1 +
 drivers/ddr/marvell/a38x/mv_ddr_common.c           |   48 +
 drivers/ddr/marvell/a38x/mv_ddr_common.h           |   21 +
 drivers/ddr/marvell/a38x/mv_ddr_plat.c             | 1451 +++++++++++++++++++
 drivers/ddr/marvell/a38x/mv_ddr_plat.h             |  237 ++++
 drivers/ddr/marvell/a38x/mv_ddr_regs.h             |  447 ++++++
 drivers/ddr/marvell/a38x/mv_ddr_spd.c              |  378 +++++
 drivers/ddr/marvell/a38x/mv_ddr_spd.h              |  290 ++++
 drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.c      |  103 ++
 drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.h      |  118 ++
 drivers/ddr/marvell/a38x/mv_ddr_topology.c         |  198 +++
 drivers/ddr/marvell/a38x/mv_ddr_topology.h         |  130 ++
 drivers/ddr/marvell/a38x/seq_exec.h                |   65 +
 drivers/ddr/marvell/a38x/silicon_if.h              |   17 -
 drivers/ddr/marvell/a38x/xor.c                     |  185 ++-
 drivers/ddr/marvell/a38x/xor.h                     |    3 +-
 60 files changed, 7998 insertions(+), 5968 deletions(-)
 delete mode 100644 drivers/ddr/marvell/a38x/ddr3_a38x.c
 delete mode 100644 drivers/ddr/marvell/a38x/ddr3_a38x.h
 delete mode 100644 drivers/ddr/marvell/a38x/ddr3_a38x_mc_static.h
 delete mode 100644 drivers/ddr/marvell/a38x/ddr3_a38x_topology.h
 delete mode 100644 drivers/ddr/marvell/a38x/ddr3_a38x_training.c
 delete mode 100644 drivers/ddr/marvell/a38x/ddr3_hws_hw_training.c
 delete mode 100644 drivers/ddr/marvell/a38x/ddr3_hws_hw_training.h
 delete mode 100644 drivers/ddr/marvell/a38x/ddr3_hws_hw_training_def.h
 delete mode 100644 drivers/ddr/marvell/a38x/ddr3_hws_sil_training.h
 delete mode 100644 drivers/ddr/marvell/a38x/ddr3_training_ip_static.h
 delete mode 100644 drivers/ddr/marvell/a38x/ddr3_training_static.c
 create mode 100644 drivers/ddr/marvell/a38x/ddr_ml_wrapper.h
 create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_build_message.c
 create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_common.c
 create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_common.h
 create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_plat.c
 create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_plat.h
 create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_regs.h
 create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_spd.c
 create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_spd.h
 create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.c
 create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.h
 create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_topology.c
 create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_topology.h
 create mode 100644 drivers/ddr/marvell/a38x/seq_exec.h
 delete mode 100644 drivers/ddr/marvell/a38x/silicon_if.h

-- 
2.16.2

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH v2 1/6] ARM: mvebu: a38x: move definition of PEX_CFG_DIRECT_ACCESS
  2018-04-09 10:12 [U-Boot] [PATCH v2 0/6] ARM: mvebu: a38x: updates to ddr training code Chris Packham
@ 2018-04-09 10:12 ` Chris Packham
  2018-04-09 10:12 ` [U-Boot] [PATCH v2 2/6] ARM: mvebu: a38x: move sys_env_device_rev_get Chris Packham
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Chris Packham @ 2018-04-09 10:12 UTC (permalink / raw)
  To: u-boot

PEX_CFG_DIRECT_ACCESS was defined in ddr3_hws_hw_training_def.h despite
only being used in the serdes code. Move this definition to ctrl_pex.h
where all the other PEX defines are. Also remove the duplicate
definition of PEX_DEVICE_AND_VENDOR_ID which is already defined in
ctrl_pex.h.

Signed-off-by: Chris Packham <judge.packham@gmail.com>
---

Changes in v2: None

 arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h          | 1 +
 drivers/ddr/marvell/a38x/ddr3_hws_hw_training_def.h | 2 --
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h
index ca8a4d206a36..d6f0d4fcd381 100644
--- a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h
+++ b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h
@@ -47,6 +47,7 @@
 
 /* Controller revision info */
 #define PEX_DEVICE_AND_VENDOR_ID	0x000
+#define PEX_CFG_DIRECT_ACCESS(if, reg)	(PEX_IF_REGS_BASE(if) + (reg))
 
 /* PCI Express Configuration Address Register */
 #define PXCAR_REG_NUM_OFFS		2
diff --git a/drivers/ddr/marvell/a38x/ddr3_hws_hw_training_def.h b/drivers/ddr/marvell/a38x/ddr3_hws_hw_training_def.h
index 06d0ab10aa2a..bca0af89a72d 100644
--- a/drivers/ddr/marvell/a38x/ddr3_hws_hw_training_def.h
+++ b/drivers/ddr/marvell/a38x/ddr3_hws_hw_training_def.h
@@ -422,8 +422,6 @@
 
 /* Power Management Clock Gating Control Register */
 #define POWER_MNG_CTRL_REG			0x18220
-#define PEX_DEVICE_AND_VENDOR_ID		0x000
-#define PEX_CFG_DIRECT_ACCESS(if, reg)	(PEX_IF_REGS_BASE(if) + (reg))
 #define PMC_PEXSTOPCLOCK_OFFS(p)	((p) < 8 ? (5 + (p)) : (18 + (p)))
 #define PMC_PEXSTOPCLOCK_MASK(p)	(1 << PMC_PEXSTOPCLOCK_OFFS(p))
 #define PMC_PEXSTOPCLOCK_EN(p)		(1 << PMC_PEXSTOPCLOCK_OFFS(p))
-- 
2.16.2

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH v2 2/6] ARM: mvebu: a38x: move sys_env_device_rev_get
  2018-04-09 10:12 [U-Boot] [PATCH v2 0/6] ARM: mvebu: a38x: updates to ddr training code Chris Packham
  2018-04-09 10:12 ` [U-Boot] [PATCH v2 1/6] ARM: mvebu: a38x: move definition of PEX_CFG_DIRECT_ACCESS Chris Packham
@ 2018-04-09 10:12 ` Chris Packham
  2018-04-09 10:12 ` [U-Boot] [PATCH v2 3/6] ARM: mvebu: a38x: remove some unused code Chris Packham
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Chris Packham @ 2018-04-09 10:12 UTC (permalink / raw)
  To: u-boot

Move sys_env_device_rev_get() from the ddr training code to
sys_env_lib.c (which currently resides with the serdes code). This
brings sys_env_device_rev_get() into line with sys_env_device_id_get()
and sys_env_model_get().

Signed-off-by: Chris Packham <judge.packham@gmail.com>
---

Changes in v2:
- remove unused #include

 arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c | 26 ++++++++++++++++++++++++--
 arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h |  1 -
 drivers/ddr/marvell/a38x/ddr3_init.c          | 24 ------------------------
 3 files changed, 24 insertions(+), 27 deletions(-)

diff --git a/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c b/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c
index cc3e5e23c0dd..ec2d89a66b0b 100644
--- a/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c
+++ b/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c
@@ -13,8 +13,6 @@
 #include "seq_exec.h"
 #include "sys_env_lib.h"
 
-#include "../../../drivers/ddr/marvell/a38x/ddr3_a38x.h"
-
 #ifdef CONFIG_ARMADA_38X
 enum unit_id sys_env_soc_unit_nums[MAX_UNITS_ID][MAX_DEV_ID_NUM] = {
 /*                     6820    6810     6811     6828     */
@@ -235,3 +233,27 @@ u32 sys_env_device_id_get(void)
 
 	return g_dev_id;
 }
+
+/*
+ * sys_env_device_rev_get - Get Marvell controller device revision number
+ *
+ * DESCRIPTION:
+ *       This function returns 8bit describing the device revision as defined
+ *       Revision ID Register.
+ *
+ * INPUT:
+ *       None.
+ *
+ * OUTPUT:
+ *       None.
+ *
+ * RETURN:
+ *       8bit desscribing Marvell controller revision number
+ */
+u8 sys_env_device_rev_get(void)
+{
+	u32 value;
+
+	value = reg_read(DEV_VERSION_ID_REG);
+	return (value & (REVISON_ID_MASK)) >> REVISON_ID_OFFS;
+}
diff --git a/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h b/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h
index a413c51043ee..15626cbca7d5 100644
--- a/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h
+++ b/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h
@@ -8,7 +8,6 @@
 #define _SYS_ENV_LIB_H
 
 #include "../../../drivers/ddr/marvell/a38x/ddr3_init.h"
-#include "../../../drivers/ddr/marvell/a38x/ddr3_hws_hw_training.h"
 
 /* Serdes definitions */
 #define COMMON_PHY_BASE_ADDR		0x18300
diff --git a/drivers/ddr/marvell/a38x/ddr3_init.c b/drivers/ddr/marvell/a38x/ddr3_init.c
index 55baad498ae5..032c4d54f359 100644
--- a/drivers/ddr/marvell/a38x/ddr3_init.c
+++ b/drivers/ddr/marvell/a38x/ddr3_init.c
@@ -108,30 +108,6 @@ static int ddr3_hws_tune_training_params(u8 dev_num);
 /* A39x revisions */
 #define MV_88F69XX_Z1_ID		0x2
 
-/*
- * sys_env_device_rev_get - Get Marvell controller device revision number
- *
- * DESCRIPTION:
- *       This function returns 8bit describing the device revision as defined
- *       Revision ID Register.
- *
- * INPUT:
- *       None.
- *
- * OUTPUT:
- *       None.
- *
- * RETURN:
- *       8bit desscribing Marvell controller revision number
- */
-u8 sys_env_device_rev_get(void)
-{
-	u32 value;
-
-	value = reg_read(DEV_VERSION_ID_REG);
-	return (value & (REVISON_ID_MASK)) >> REVISON_ID_OFFS;
-}
-
 /*
  * sys_env_dlb_config_ptr_get
  *
-- 
2.16.2

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH v2 3/6] ARM: mvebu: a38x: remove some unused code
  2018-04-09 10:12 [U-Boot] [PATCH v2 0/6] ARM: mvebu: a38x: updates to ddr training code Chris Packham
  2018-04-09 10:12 ` [U-Boot] [PATCH v2 1/6] ARM: mvebu: a38x: move definition of PEX_CFG_DIRECT_ACCESS Chris Packham
  2018-04-09 10:12 ` [U-Boot] [PATCH v2 2/6] ARM: mvebu: a38x: move sys_env_device_rev_get Chris Packham
@ 2018-04-09 10:12 ` Chris Packham
  2018-04-09 10:12 ` [U-Boot] [PATCH v2 4/6] ARM: mvebu: a38x: sync ddr training code with upstream Chris Packham
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Chris Packham @ 2018-04-09 10:12 UTC (permalink / raw)
  To: u-boot

No in-tree code defines SUPPORT_STATIC_DUNIT_CONFIG or
STATIC_ALGO_SUPPORT. Remove ddr3_a38x_mc_static.h and use unifdef to
remove unused sections in the rest of the ddr/marvell/a38x code.

Signed-off-by: Chris Packham <judge.packham@gmail.com>
---
Much of this code is moved/removed in the updated DDR code so this
commit helps minimise the final delta.

Changes in v2: New

 drivers/ddr/marvell/a38x/ddr3_a38x.c            |  51 ---
 drivers/ddr/marvell/a38x/ddr3_a38x_mc_static.h  | 226 ------------
 drivers/ddr/marvell/a38x/ddr3_debug.c           |   9 -
 drivers/ddr/marvell/a38x/ddr3_init.c            |  29 --
 drivers/ddr/marvell/a38x/ddr3_init.h            |   1 -
 drivers/ddr/marvell/a38x/ddr3_training.c        |  41 ---
 drivers/ddr/marvell/a38x/ddr3_training_static.c | 438 ------------------------
 7 files changed, 795 deletions(-)
 delete mode 100644 drivers/ddr/marvell/a38x/ddr3_a38x_mc_static.h

diff --git a/drivers/ddr/marvell/a38x/ddr3_a38x.c b/drivers/ddr/marvell/a38x/ddr3_a38x.c
index c082122f25c3..22390325003d 100644
--- a/drivers/ddr/marvell/a38x/ddr3_a38x.c
+++ b/drivers/ddr/marvell/a38x/ddr3_a38x.c
@@ -77,41 +77,6 @@ struct trip_delay_element a38x_board_round_trip_delay_array[] = {
 	{ 4282, 6160 }	/* ECC PUP */
 };
 
-#ifdef STATIC_ALGO_SUPPORT
-/* package trace */
-static struct trip_delay_element a38x_package_round_trip_delay_array[] = {
-	/* IF BUS DQ_DELAY CK_DELAY */
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 }
-};
-
-static int a38x_silicon_delay_offset[] = {
-	/* board 0 */
-	0,
-	/* board 1 */
-	0,
-	/* board 2 */
-	0
-};
-#endif
 
 static u8 a38x_bw_per_freq[DDR_FREQ_LIMIT] = {
 	0x3,			/* DDR_FREQ_100 */
@@ -368,22 +333,6 @@ static int ddr3_tip_init_a38x_silicon(u32 dev_num, u32 board_id)
 
 	ddr3_tip_register_dq_table(dev_num, dq_bit_map_2_phy_pin);
 
-#ifdef STATIC_ALGO_SUPPORT
-	{
-		struct hws_tip_static_config_info static_config;
-		u32 board_offset =
-		    board_id * A38X_NUMBER_OF_INTERFACES *
-		    tm->num_of_bus_per_interface;
-
-		static_config.silicon_delay =
-			a38x_silicon_delay_offset[board_id];
-		static_config.package_trace_arr =
-			a38x_package_round_trip_delay_array;
-		static_config.board_trace_arr =
-			&a38x_board_round_trip_delay_array[board_offset];
-		ddr3_tip_init_static_config_db(dev_num, &static_config);
-	}
-#endif
 	status = ddr3_tip_a38x_get_init_freq(dev_num, &ddr_freq);
 	if (MV_OK != status) {
 		DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR,
diff --git a/drivers/ddr/marvell/a38x/ddr3_a38x_mc_static.h b/drivers/ddr/marvell/a38x/ddr3_a38x_mc_static.h
deleted file mode 100644
index b879a010311b..000000000000
--- a/drivers/ddr/marvell/a38x/ddr3_a38x_mc_static.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- *
- * SPDX-License-Identifier:	GPL-2.0
- */
-
-#ifndef _DDR3_A38X_MC_STATIC_H
-#define _DDR3_A38X_MC_STATIC_H
-
-#include "ddr3_a38x.h"
-
-#ifdef SUPPORT_STATIC_DUNIT_CONFIG
-
-#ifdef CONFIG_CUSTOMER_BOARD_SUPPORT
-static struct reg_data ddr3_customer_800[] = {
-	/* parameters for customer board (based on 800MHZ) */
-	{0x1400,	0x7b00cc30, 0xffffffff},
-	{0x1404,	0x36301820, 0xffffffff},
-	{0x1408,	0x5415baab, 0xffffffff},
-	{0x140c,	0x38411def, 0xffffffff},
-	{0x1410,	0x18300000, 0xffffffff},
-	{0x1414,	0x00000700, 0xffffffff},
-	{0x1424,	0x0060f3ff, 0xffffffff},
-	{0x1428,	0x0011a940, 0xffffffff},
-	{0x142c,	0x28c5134,  0xffffffff},
-	{0x1474,	0x00000000, 0xffffffff},
-	{0x147c,	0x0000d771, 0xffffffff},
-	{0x1494,	0x00030000, 0xffffffff},
-	{0x149c,	0x00000300, 0xffffffff},
-	{0x14a8,	0x00000000, 0xffffffff},
-	{0x14cc,	0xbd09000d, 0xffffffff},
-	{0x1504,	0xfffffff1, 0xffffffff},
-	{0x150c,	0xffffffe5, 0xffffffff},
-	{0x1514,	0x00000000, 0xffffffff},
-	{0x151c,	0x00000000, 0xffffffff},
-	{0x1538,	0x00000b0b, 0xffffffff},
-	{0x153c,	0x00000c0c, 0xffffffff},
-	{0x15d0,	0x00000670, 0xffffffff},
-	{0x15d4,	0x00000046, 0xffffffff},
-	{0x15d8,	0x00000010, 0xffffffff},
-	{0x15dc,	0x00000000, 0xffffffff},
-	{0x15e0,	0x00000023, 0xffffffff},
-	{0x15e4,	0x00203c18, 0xffffffff},
-	{0x15ec,	0xf8000019, 0xffffffff},
-	{0x16a0,	0xcc000006, 0xffffffff},	/* Clock Delay */
-	{0xe4124,	0x08008073, 0xffffffff},	/* AVS BG default */
-	{0, 0, 0}
-};
-
-#else /* CONFIG_CUSTOMER_BOARD_SUPPORT */
-
-struct reg_data ddr3_a38x_933[MV_MAX_DDR3_STATIC_SIZE] = {
-	/* parameters for 933MHZ */
-	{0x1400,	0x7b00ce3a, 0xffffffff},
-	{0x1404,	0x36301820, 0xffffffff},
-	{0x1408,	0x7417eccf, 0xffffffff},
-	{0x140c,	0x3e421f98, 0xffffffff},
-	{0x1410,	0x1a300000, 0xffffffff},
-	{0x1414,	0x00000700, 0xffffffff},
-	{0x1424,	0x0060f3ff, 0xffffffff},
-	{0x1428,	0x0013ca50, 0xffffffff},
-	{0x142c,	0x028c5165, 0xffffffff},
-	{0x1474,	0x00000000, 0xffffffff},
-	{0x147c,	0x0000e871, 0xffffffff},
-	{0x1494,	0x00010000, 0xffffffff},
-	{0x149c,	0x00000001, 0xffffffff},
-	{0x14a8,	0x00000000, 0xffffffff},
-	{0x14cc,	0xbd09000d, 0xffffffff},
-	{0x1504,	0xffffffe1, 0xffffffff},
-	{0x150c,	0xffffffe5, 0xffffffff},
-	{0x1514,	0x00000000, 0xffffffff},
-	{0x151c,	0x00000000, 0xffffffff},
-	{0x1538,	0x00000d0d, 0xffffffff},
-	{0x153c,	0x00000d0d, 0xffffffff},
-	{0x15d0,	0x00000608, 0xffffffff},
-	{0x15d4,	0x00000044, 0xffffffff},
-	{0x15d8,	0x00000020, 0xffffffff},
-	{0x15dc,	0x00000000, 0xffffffff},
-	{0x15e0,	0x00000021, 0xffffffff},
-	{0x15e4,	0x00203c18, 0xffffffff},
-	{0x15ec,	0xf8000019, 0xffffffff},
-	{0x16a0,	0xcc000006, 0xffffffff},	/* Clock Delay */
-	{0xe4124,	0x08008073, 0xffffffff},	/* AVS BG default */
-	{0, 0, 0}
-};
-
-static struct reg_data ddr3_a38x_800[] = {
-	/* parameters for 800MHZ */
-	{0x1400,	0x7b00cc30, 0xffffffff},
-	{0x1404,	0x36301820, 0xffffffff},
-	{0x1408,	0x5415baab, 0xffffffff},
-	{0x140c,	0x38411def, 0xffffffff},
-	{0x1410,	0x18300000, 0xffffffff},
-	{0x1414,	0x00000700, 0xffffffff},
-	{0x1424,	0x0060f3ff, 0xffffffff},
-	{0x1428,	0x0011a940, 0xffffffff},
-	{0x142c,	0x28c5134,  0xffffffff},
-	{0x1474,	0x00000000, 0xffffffff},
-	{0x147c,	0x0000d771, 0xffffffff},
-	{0x1494,	0x00030000, 0xffffffff},
-	{0x149c,	0x00000300, 0xffffffff},
-	{0x14a8,	0x00000000, 0xffffffff},
-	{0x14cc,	0xbd09000d, 0xffffffff},
-	{0x1504,	0xfffffff1, 0xffffffff},
-	{0x150c,	0xffffffe5, 0xffffffff},
-	{0x1514,	0x00000000, 0xffffffff},
-	{0x151c,	0x00000000, 0xffffffff},
-	{0x1538,	0x00000b0b, 0xffffffff},
-	{0x153c,	0x00000c0c, 0xffffffff},
-	{0x15d0,	0x00000670, 0xffffffff},
-	{0x15d4,	0x00000046, 0xffffffff},
-	{0x15d8,	0x00000010, 0xffffffff},
-	{0x15dc,	0x00000000, 0xffffffff},
-	{0x15e0,	0x00000023, 0xffffffff},
-	{0x15e4,	0x00203c18, 0xffffffff},
-	{0x15ec,	0xf8000019, 0xffffffff},
-	{0x16a0,	0xcc000006, 0xffffffff},	/* Clock Delay */
-	{0xe4124,	0x08008073, 0xffffffff},	/* AVS BG default */
-	{0,   0, 0}
-};
-
-static struct reg_data ddr3_a38x_667[] = {
-	/* parameters for 667MHZ */
-	/* DDR SDRAM Configuration Register */
-	{0x1400,    0x7b00ca28, 0xffffffff},
-	/* Dunit Control Low Register - kw28 bit12 low (disable CLK1) */
-	{0x1404,    0x36301820, 0xffffffff},
-	/* DDR SDRAM Timing (Low) Register */
-	{0x1408,    0x43149997, 0xffffffff},
-	/* DDR SDRAM Timing (High) Register */
-	{0x140c,    0x38411bc7, 0xffffffff},
-	/* DDR SDRAM Address Control Register */
-	{0x1410,    0x14330000, 0xffffffff},
-	/* DDR SDRAM Open Pages Control Register */
-	{0x1414,    0x00000700, 0xffffffff},
-	/* Dunit Control High Register (2 :1 - bits 15:12 = 0xd) */
-	{0x1424,    0x0060f3ff, 0xffffffff},
-	/* Dunit Control High Register */
-	{0x1428,    0x000f8830, 0xffffffff},
-	/* Dunit Control High Register  (2:1 -  bit 29 = '1') */
-	{0x142c,    0x28c50f8,  0xffffffff},
-	{0x147c,    0x0000c671, 0xffffffff},
-	/* DDR SDRAM ODT Control (Low) Register */
-	{0x1494,    0x00030000, 0xffffffff},
-	/* DDR SDRAM ODT Control (High) Register, will be configured at WL */
-	{0x1498,    0x00000000, 0xffffffff},
-	/* DDR Dunit ODT Control Register */
-	{0x149c,    0x00000300, 0xffffffff},
-	{0x14a8,    0x00000000, 0xffffffff}, /*  */
-	{0x14cc,    0xbd09000d, 0xffffffff}, /*  */
-	{0x1474,    0x00000000, 0xffffffff},
-	/* Read Data Sample Delays Register */
-	{0x1538,    0x00000009, 0xffffffff},
-	/* Read Data Ready Delay Register */
-	{0x153c,    0x0000000c, 0xffffffff},
-	{0x1504,    0xfffffff1, 0xffffffff}, /*  */
-	{0x150c,    0xffffffe5, 0xffffffff}, /*  */
-	{0x1514,    0x00000000, 0xffffffff}, /*  */
-	{0x151c,    0x0,	0xffffffff}, /*  */
-	{0x15d0,    0x00000650, 0xffffffff}, /* MR0 */
-	{0x15d4,    0x00000046, 0xffffffff}, /* MR1 */
-	{0x15d8,    0x00000010, 0xffffffff}, /* MR2 */
-	{0x15dc,    0x00000000, 0xffffffff}, /* MR3 */
-	{0x15e0,    0x23,	0xffffffff}, /*  */
-	{0x15e4,    0x00203c18, 0xffffffff}, /* ZQC Configuration Register */
-	{0x15ec,    0xf8000019, 0xffffffff}, /* DDR PHY */
-	{0x16a0,    0xcc000006, 0xffffffff}, /* Clock Delay */
-	{0xe4124,   0x08008073, 0xffffffff}, /* AVS BG default */
-	{0, 0, 0}
-};
-
-static struct reg_data ddr3_a38x_533[] = {
-	/* parameters for 533MHZ */
-	/* DDR SDRAM Configuration Register */
-	{0x1400,    0x7b00d040, 0xffffffff},
-	/* Dunit Control Low Register - kw28 bit12 low (disable CLK1) */
-	{0x1404,    0x36301820, 0xffffffff},
-	/* DDR SDRAM Timing (Low) Register */
-	{0x1408,    0x33137772, 0xffffffff},
-	/* DDR SDRAM Timing (High) Register */
-	{0x140c,    0x3841199f, 0xffffffff},
-	/* DDR SDRAM Address Control Register */
-	{0x1410,    0x10330000, 0xffffffff},
-	/* DDR SDRAM Open Pages Control Register */
-	{0x1414,    0x00000700, 0xffffffff},
-	/* Dunit Control High Register (2 :1 - bits 15:12 = 0xd) */
-	{0x1424,    0x0060f3ff, 0xffffffff},
-	/* Dunit Control High Register */
-	{0x1428,    0x000d6720, 0xffffffff},
-	/* Dunit Control High Register  (2:1 -  bit 29 = '1') */
-	{0x142c,    0x028c50c3, 0xffffffff},
-	{0x147c,    0x0000b571, 0xffffffff},
-	/* DDR SDRAM ODT Control (Low) Register */
-	{0x1494,    0x00030000, 0xffffffff},
-	/* DDR SDRAM ODT Control (High) Register, will be configured at WL */
-	{0x1498,    0x00000000, 0xffffffff},
-	/* DDR Dunit ODT Control Register */
-	{0x149c,    0x00000003, 0xffffffff},
-	{0x14a8,    0x00000000, 0xffffffff}, /*  */
-	{0x14cc,    0xbd09000d, 0xffffffff}, /*  */
-	{0x1474,    0x00000000, 0xffffffff},
-	/* Read Data Sample Delays Register */
-	{0x1538,    0x00000707, 0xffffffff},
-	/* Read Data Ready Delay Register */
-	{0x153c,    0x00000707, 0xffffffff},
-	{0x1504,    0xffffffe1, 0xffffffff}, /*  */
-	{0x150c,    0xffffffe5, 0xffffffff}, /*  */
-	{0x1514,    0x00000000, 0xffffffff}, /*  */
-	{0x151c,    0x00000000,	0xffffffff}, /*  */
-	{0x15d0,    0x00000630, 0xffffffff}, /* MR0 */
-	{0x15d4,    0x00000046, 0xffffffff}, /* MR1 */
-	{0x15d8,    0x00000008, 0xffffffff}, /* MR2 */
-	{0x15dc,    0x00000000, 0xffffffff}, /* MR3 */
-	{0x15e0,    0x00000023,	0xffffffff}, /*  */
-	{0x15e4,    0x00203c18, 0xffffffff}, /* ZQC Configuration Register */
-	{0x15ec,    0xf8000019, 0xffffffff}, /* DDR PHY */
-	{0x16a0,    0xcc000006, 0xffffffff}, /* Clock Delay */
-	{0xe4124,   0x08008073, 0xffffffff}, /* AVS BG default */
-	{0, 0, 0}
-};
-
-#endif /* CONFIG_CUSTOMER_BOARD_SUPPORT */
-
-#endif /* SUPPORT_STATIC_DUNIT_CONFIG */
-
-#endif /* _DDR3_A38X_MC_STATIC_H */
diff --git a/drivers/ddr/marvell/a38x/ddr3_debug.c b/drivers/ddr/marvell/a38x/ddr3_debug.c
index a704a3e9d314..f0c8daa4b62c 100644
--- a/drivers/ddr/marvell/a38x/ddr3_debug.c
+++ b/drivers/ddr/marvell/a38x/ddr3_debug.c
@@ -868,15 +868,6 @@ static int ddr3_tip_access_atr(u32 dev_num, u32 flag_id, u32 value, u32 **ptr)
 	case 0x25:
 		*ptr = (u32 *)&is_adll_calib_before_init;
 		break;
-#ifdef STATIC_ALGO_SUPPORT
-	case 0x26:
-		*ptr = (u32 *)&(silicon_delay[0]);
-		break;
-
-	case 0x27:
-		*ptr = (u32 *)&wl_debug_delay;
-		break;
-#endif
 	case 0x28:
 		*ptr = (u32 *)&is_tune_result;
 		break;
diff --git a/drivers/ddr/marvell/a38x/ddr3_init.c b/drivers/ddr/marvell/a38x/ddr3_init.c
index 032c4d54f359..4790ec1d8174 100644
--- a/drivers/ddr/marvell/a38x/ddr3_init.c
+++ b/drivers/ddr/marvell/a38x/ddr3_init.c
@@ -60,20 +60,6 @@ struct dram_modes {
 };
 
 struct dram_modes ddr_modes[] = {
-#ifdef SUPPORT_STATIC_DUNIT_CONFIG
-	/* Conf name, CPUFreq, Fab_freq, Chip ID, Chip/Board, MC regs*/
-#ifdef CONFIG_CUSTOMER_BOARD_SUPPORT
-	{"a38x_customer_0_800", DDR_FREQ_800, 0, 0x0, A38X_CUSTOMER_BOARD_ID0,
-	 ddr3_customer_800},
-	{"a38x_customer_1_800", DDR_FREQ_800, 0, 0x0, A38X_CUSTOMER_BOARD_ID1,
-	 ddr3_customer_800},
-#else
-	{"a38x_533", DDR_FREQ_533, 0, 0x0, MARVELL_BOARD, ddr3_a38x_533},
-	{"a38x_667", DDR_FREQ_667, 0, 0x0, MARVELL_BOARD, ddr3_a38x_667},
-	{"a38x_800", DDR_FREQ_800, 0, 0x0, MARVELL_BOARD, ddr3_a38x_800},
-	{"a38x_933", DDR_FREQ_933, 0, 0x0, MARVELL_BOARD, ddr3_a38x_933},
-#endif
-#endif
 };
 #endif /* defined(CONFIG_ARMADA_38X) */
 
@@ -92,9 +78,6 @@ static char *ddr_type = "DDR3";
  */
 u8 generic_init_controller = 1;
 
-#ifdef SUPPORT_STATIC_DUNIT_CONFIG
-static u32 ddr3_get_static_ddr_mode(void);
-#endif
 static int ddr3_hws_tune_training_params(u8 dev_num);
 
 /* device revision */
@@ -343,18 +326,6 @@ int ddr3_init(void)
 	/* Set X-BAR windows for the training sequence */
 	ddr3_save_and_set_training_windows(win);
 
-#ifdef SUPPORT_STATIC_DUNIT_CONFIG
-	/*
-	 * Load static controller configuration (in case dynamic/generic init
-	 * is not enabled
-	 */
-	if (generic_init_controller == 0) {
-		ddr3_tip_init_specific_reg_config(0,
-						  ddr_modes
-						  [ddr3_get_static_ddr_mode
-						   ()].regs);
-	}
-#endif
 
 	/* Tune training algo paramteres */
 	status = ddr3_hws_tune_training_params(0);
diff --git a/drivers/ddr/marvell/a38x/ddr3_init.h b/drivers/ddr/marvell/a38x/ddr3_init.h
index a4c75a9fa68f..cbf072cdef6f 100644
--- a/drivers/ddr/marvell/a38x/ddr3_init.h
+++ b/drivers/ddr/marvell/a38x/ddr3_init.h
@@ -9,7 +9,6 @@
 
 #if defined(CONFIG_ARMADA_38X)
 #include "ddr3_a38x.h"
-#include "ddr3_a38x_mc_static.h"
 #include "ddr3_a38x_topology.h"
 #endif
 #include "ddr3_hws_hw_training.h"
diff --git a/drivers/ddr/marvell/a38x/ddr3_training.c b/drivers/ddr/marvell/a38x/ddr3_training.c
index ef471e565efd..f9e11591d992 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training.c
+++ b/drivers/ddr/marvell/a38x/ddr3_training.c
@@ -636,12 +636,6 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_
 				      MASK_ALL_BITS));
 		}
 	} else {
-#ifdef STATIC_ALGO_SUPPORT
-		CHECK_STATUS(ddr3_tip_static_init_controller(dev_num));
-#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X)
-		CHECK_STATUS(ddr3_tip_static_phy_init_controller(dev_num));
-#endif
-#endif /* STATIC_ALGO_SUPPORT */
 	}
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
@@ -815,25 +809,6 @@ int hws_ddr3_tip_run_alg(u32 dev_num, enum hws_algo_type algo_type)
 	if (algo_type == ALGO_TYPE_DYNAMIC) {
 		ret = ddr3_tip_ddr3_auto_tune(dev_num);
 	} else {
-#ifdef STATIC_ALGO_SUPPORT
-		{
-			enum hws_ddr_freq freq;
-			freq = init_freq;
-
-			/* add to mask */
-			if (is_adll_calib_before_init != 0) {
-				printf("with adll calib before init\n");
-				adll_calibration(dev_num, ACCESS_TYPE_MULTICAST,
-						 0, freq);
-			}
-			/*
-			 * Frequency per interface is not relevant,
-			 * only interface 0
-			 */
-			ret = ddr3_tip_run_static_alg(dev_num,
-						      freq);
-		}
-#endif
 	}
 
 	if (ret != MV_OK) {
@@ -2028,22 +2003,6 @@ static int ddr3_tip_ddr3_training_main_flow(u32 dev_num)
 		}
 	}
 
-#ifdef STATIC_ALGO_SUPPORT
-	if (mask_tune_func & STATIC_LEVELING_MASK_BIT) {
-		training_stage = STATIC_LEVELING;
-		DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
-				  ("STATIC_LEVELING_MASK_BIT\n"));
-		ret = ddr3_tip_run_static_alg(dev_num, freq);
-		if (is_reg_dump != 0)
-			ddr3_tip_reg_dump(dev_num);
-		if (ret != MV_OK) {
-			DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
-					  ("ddr3_tip_run_static_alg failure\n"));
-			if (debug_mode == 0)
-				return MV_FAIL;
-		}
-	}
-#endif
 
 	if (mask_tune_func & SET_LOW_FREQ_MASK_BIT) {
 		training_stage = SET_LOW_FREQ;
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_static.c b/drivers/ddr/marvell/a38x/ddr3_training_static.c
index b73bbf4f1b0d..318634eb90dd 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training_static.c
+++ b/drivers/ddr/marvell/a38x/ddr3_training_static.c
@@ -26,444 +26,6 @@ u32 g_odt_config_1cs = 0x10000;
 u32 g_rtt_nom = 0x44;
 u32 g_dic = 0x2;
 
-#ifdef STATIC_ALGO_SUPPORT
-
-#define PARAM_NOT_CARE		0
-#define MAX_STATIC_SEQ		48
-
-u32 silicon_delay[HWS_MAX_DEVICE_NUM];
-struct hws_tip_static_config_info static_config[HWS_MAX_DEVICE_NUM];
-static reg_data *static_init_controller_config[HWS_MAX_DEVICE_NUM];
-
-/* debug delay in write leveling */
-int wl_debug_delay = 0;
-/* pup register #3 for functional board */
-int function_reg_value = 8;
-u32 silicon;
-
-u32 read_ready_delay_phase_offset[] = { 4, 4, 4, 4, 6, 6, 6, 6 };
-
-static struct cs_element chip_select_map[] = {
-	/* CS Value (single only)  Num_CS */
-	{0, 0},
-	{0, 1},
-	{1, 1},
-	{0, 2},
-	{2, 1},
-	{0, 2},
-	{0, 2},
-	{0, 3},
-	{3, 1},
-	{0, 2},
-	{0, 2},
-	{0, 3},
-	{0, 2},
-	{0, 3},
-	{0, 3},
-	{0, 4}
-};
-
-/*
- * Register static init controller DB
- */
-int ddr3_tip_init_specific_reg_config(u32 dev_num, reg_data *reg_config_arr)
-{
-	static_init_controller_config[dev_num] = reg_config_arr;
-	return MV_OK;
-}
-
-/*
- * Register static info DB
- */
-int ddr3_tip_init_static_config_db(
-	u32 dev_num, struct hws_tip_static_config_info *static_config_info)
-{
-	static_config[dev_num].board_trace_arr =
-		static_config_info->board_trace_arr;
-	static_config[dev_num].package_trace_arr =
-		static_config_info->package_trace_arr;
-	silicon_delay[dev_num] = static_config_info->silicon_delay;
-
-	return MV_OK;
-}
-
-/*
- * Static round trip flow - Calculates the total round trip delay.
- */
-int ddr3_tip_static_round_trip_arr_build(u32 dev_num,
-					 struct trip_delay_element *table_ptr,
-					 int is_wl, u32 *round_trip_delay_arr)
-{
-	u32 bus_index, global_bus;
-	u32 if_id;
-	u32 bus_per_interface;
-	int sign;
-	u32 temp;
-	u32 board_trace;
-	struct trip_delay_element *pkg_delay_ptr;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
-
-	/*
-	 * In WL we calc the diff between Clock to DQs in RL we sum the round
-	 * trip of Clock and DQs
-	 */
-	sign = (is_wl) ? -1 : 1;
-
-	bus_per_interface = GET_TOPOLOGY_NUM_OF_BUSES();
-
-	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-		for (bus_index = 0; bus_index < bus_per_interface;
-		     bus_index++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, bus_index);
-			global_bus = (if_id * bus_per_interface) + bus_index;
-
-			/* calculate total trip delay (package and board) */
-			board_trace = (table_ptr[global_bus].dqs_delay * sign) +
-				table_ptr[global_bus].ck_delay;
-			temp = (board_trace * 163) / 1000;
-
-			/* Convert the length to delay in psec units */
-			pkg_delay_ptr =
-				static_config[dev_num].package_trace_arr;
-			round_trip_delay_arr[global_bus] = temp +
-				(int)(pkg_delay_ptr[global_bus].dqs_delay *
-				      sign) +
-				(int)pkg_delay_ptr[global_bus].ck_delay +
-				(int)((is_wl == 1) ? wl_debug_delay :
-				      (int)silicon_delay[dev_num]);
-			DEBUG_TRAINING_STATIC_IP(
-				DEBUG_LEVEL_TRACE,
-				("Round Trip Build round_trip_delay_arr[0x%x]: 0x%x    temp 0x%x\n",
-				 global_bus, round_trip_delay_arr[global_bus],
-				 temp));
-		}
-	}
-
-	return MV_OK;
-}
-
-/*
- * Write leveling for static flow - calculating the round trip delay of the
- * DQS signal.
- */
-int ddr3_tip_write_leveling_static_config(u32 dev_num, u32 if_id,
-					  enum hws_ddr_freq frequency,
-					  u32 *round_trip_delay_arr)
-{
-	u32 bus_index;		/* index to the bus loop */
-	u32 bus_start_index;
-	u32 bus_per_interface;
-	u32 phase = 0;
-	u32 adll = 0, adll_cen, adll_inv, adll_final;
-	u32 adll_period = MEGA / freq_val[frequency] / 64;
-
-	DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
-				 ("ddr3_tip_write_leveling_static_config\n"));
-	DEBUG_TRAINING_STATIC_IP(
-		DEBUG_LEVEL_TRACE,
-		("dev_num 0x%x IF 0x%x freq %d (adll_period 0x%x)\n",
-		 dev_num, if_id, frequency, adll_period));
-
-	bus_per_interface = GET_TOPOLOGY_NUM_OF_BUSES();
-	bus_start_index = if_id * bus_per_interface;
-	for (bus_index = bus_start_index;
-	     bus_index < (bus_start_index + bus_per_interface); bus_index++) {
-		VALIDATE_ACTIVE(tm->bus_act_mask, bus_index);
-		phase = round_trip_delay_arr[bus_index] / (32 * adll_period);
-		adll = (round_trip_delay_arr[bus_index] -
-			(phase * 32 * adll_period)) / adll_period;
-		adll = (adll > 31) ? 31 : adll;
-		adll_cen = 16 + adll;
-		adll_inv = adll_cen / 32;
-		adll_final = adll_cen - (adll_inv * 32);
-		adll_final = (adll_final > 31) ? 31 : adll_final;
-
-		DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
-					 ("\t%d - phase 0x%x adll 0x%x\n",
-					  bus_index, phase, adll));
-		/*
-		 * Writing to all 4 phy of Interface number,
-		 * bit 0 \96 4 \96 ADLL, bit 6-8 phase
-		 */
-		CHECK_STATUS(ddr3_tip_bus_read_modify_write
-			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      (bus_index % 4), DDR_PHY_DATA,
-			      PHY_WRITE_DELAY(cs),
-			      ((phase << 6) + (adll & 0x1f)), 0x1df));
-		CHECK_STATUS(ddr3_tip_bus_write
-			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      ACCESS_TYPE_UNICAST, (bus_index % 4),
-			      DDR_PHY_DATA, WRITE_CENTRALIZATION_PHY_REG,
-			      ((adll_inv & 0x1) << 5) + adll_final));
-	}
-
-	return MV_OK;
-}
-
-/*
- * Read leveling for static flow
- */
-int ddr3_tip_read_leveling_static_config(u32 dev_num,
-					 u32 if_id,
-					 enum hws_ddr_freq frequency,
-					 u32 *total_round_trip_delay_arr)
-{
-	u32 cs, data0, data1, data3 = 0;
-	u32 bus_index;		/* index to the bus loop */
-	u32 bus_start_index;
-	u32 phase0, phase1, max_phase;
-	u32 adll0, adll1;
-	u32 cl_value;
-	u32 min_delay;
-	u32 sdr_period = MEGA / freq_val[frequency];
-	u32 ddr_period = MEGA / freq_val[frequency] / 2;
-	u32 adll_period = MEGA / freq_val[frequency] / 64;
-	enum hws_speed_bin speed_bin_index;
-	u32 rd_sample_dly[MAX_CS_NUM] = { 0 };
-	u32 rd_ready_del[MAX_CS_NUM] = { 0 };
-	u32 bus_per_interface = GET_TOPOLOGY_NUM_OF_BUSES();
-	struct hws_topology_map *tm = ddr3_get_topology_map();
-
-	DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
-				 ("ddr3_tip_read_leveling_static_config\n"));
-	DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
-				 ("dev_num 0x%x ifc 0x%x freq %d\n", dev_num,
-				  if_id, frequency));
-	DEBUG_TRAINING_STATIC_IP(
-		DEBUG_LEVEL_TRACE,
-		("Sdr_period 0x%x Ddr_period 0x%x adll_period 0x%x\n",
-		 sdr_period, ddr_period, adll_period));
-
-	if (tm->interface_params[first_active_if].memory_freq ==
-	    frequency) {
-		cl_value = tm->interface_params[first_active_if].cas_l;
-		DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
-					 ("cl_value 0x%x\n", cl_value));
-	} else {
-		speed_bin_index = tm->interface_params[if_id].speed_bin_index;
-		cl_value = cas_latency_table[speed_bin_index].cl_val[frequency];
-		DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
-					 ("cl_value 0x%x speed_bin_index %d\n",
-					  cl_value, speed_bin_index));
-	}
-
-	bus_start_index = if_id * bus_per_interface;
-
-	for (bus_index = bus_start_index;
-	     bus_index < (bus_start_index + bus_per_interface);
-	     bus_index += 2) {
-		VALIDATE_ACTIVE(tm->bus_act_mask, bus_index);
-		cs = chip_select_map[
-			tm->interface_params[if_id].as_bus_params[
-				(bus_index % 4)].cs_bitmask].cs_num;
-
-		/* read sample delay calculation */
-		min_delay = (total_round_trip_delay_arr[bus_index] <
-			     total_round_trip_delay_arr[bus_index + 1]) ?
-			total_round_trip_delay_arr[bus_index] :
-			total_round_trip_delay_arr[bus_index + 1];
-		/* round down */
-		rd_sample_dly[cs] = 2 * (min_delay / (sdr_period * 2));
-		DEBUG_TRAINING_STATIC_IP(
-			DEBUG_LEVEL_TRACE,
-			("\t%d - min_delay 0x%x cs 0x%x rd_sample_dly[cs] 0x%x\n",
-			 bus_index, min_delay, cs, rd_sample_dly[cs]));
-
-		/* phase calculation */
-		phase0 = (total_round_trip_delay_arr[bus_index] -
-			  (sdr_period * rd_sample_dly[cs])) / (ddr_period);
-		phase1 = (total_round_trip_delay_arr[bus_index + 1] -
-			  (sdr_period * rd_sample_dly[cs])) / (ddr_period);
-		max_phase = (phase0 > phase1) ? phase0 : phase1;
-		DEBUG_TRAINING_STATIC_IP(
-			DEBUG_LEVEL_TRACE,
-			("\tphase0 0x%x phase1 0x%x max_phase 0x%x\n",
-			 phase0, phase1, max_phase));
-
-		/* ADLL calculation */
-		adll0 = (u32)((total_round_trip_delay_arr[bus_index] -
-			       (sdr_period * rd_sample_dly[cs]) -
-			       (ddr_period * phase0)) / adll_period);
-		adll0 = (adll0 > 31) ? 31 : adll0;
-		adll1 = (u32)((total_round_trip_delay_arr[bus_index + 1] -
-			       (sdr_period * rd_sample_dly[cs]) -
-			       (ddr_period * phase1)) / adll_period);
-		adll1 = (adll1 > 31) ? 31 : adll1;
-
-		/* The Read delay close the Read FIFO */
-		rd_ready_del[cs] = rd_sample_dly[cs] +
-			read_ready_delay_phase_offset[max_phase];
-		DEBUG_TRAINING_STATIC_IP(
-			DEBUG_LEVEL_TRACE,
-			("\tadll0 0x%x adll1 0x%x rd_ready_del[cs] 0x%x\n",
-			 adll0, adll1, rd_ready_del[cs]));
-
-		/*
-		 * Write to the phy of Interface (bit 0 \96 4 \96 ADLL,
-		 * bit 6-8 phase)
-		 */
-		data0 = ((phase0 << 6) + (adll0 & 0x1f));
-		data1 = ((phase1 << 6) + (adll1 & 0x1f));
-
-		CHECK_STATUS(ddr3_tip_bus_read_modify_write
-			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      (bus_index % 4), DDR_PHY_DATA, PHY_READ_DELAY(cs),
-			      data0, 0x1df));
-		CHECK_STATUS(ddr3_tip_bus_read_modify_write
-			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      ((bus_index + 1) % 4), DDR_PHY_DATA,
-			      PHY_READ_DELAY(cs), data1, 0x1df));
-	}
-
-	for (bus_index = 0; bus_index < bus_per_interface; bus_index++) {
-		VALIDATE_ACTIVE(tm->bus_act_mask, bus_index);
-		CHECK_STATUS(ddr3_tip_bus_read_modify_write
-			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      bus_index, DDR_PHY_DATA, 0x3, data3, 0x1f));
-	}
-	CHECK_STATUS(ddr3_tip_if_write
-		     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-		      READ_DATA_SAMPLE_DELAY,
-		      (rd_sample_dly[0] + cl_value) + (rd_sample_dly[1] << 8),
-		      MASK_ALL_BITS));
-
-	/* Read_ready_del0 bit 0-4 , CS bits 8-12 */
-	CHECK_STATUS(ddr3_tip_if_write
-		     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-		      READ_DATA_READY_DELAY,
-		      rd_ready_del[0] + (rd_ready_del[1] << 8) + cl_value,
-		      MASK_ALL_BITS));
-
-	return MV_OK;
-}
-
-/*
- * DDR3 Static flow
- */
-int ddr3_tip_run_static_alg(u32 dev_num, enum hws_ddr_freq freq)
-{
-	u32 if_id = 0;
-	struct trip_delay_element *table_ptr;
-	u32 wl_total_round_trip_delay_arr[MAX_TOTAL_BUS_NUM];
-	u32 rl_total_round_trip_delay_arr[MAX_TOTAL_BUS_NUM];
-	struct init_cntr_param init_cntr_prm;
-	int ret;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
-
-	DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
-				 ("ddr3_tip_run_static_alg"));
-
-	init_cntr_prm.do_mrs_phy = 1;
-	init_cntr_prm.is_ctrl64_bit = 0;
-	init_cntr_prm.init_phy = 1;
-	ret = hws_ddr3_tip_init_controller(dev_num, &init_cntr_prm);
-	if (ret != MV_OK) {
-		DEBUG_TRAINING_STATIC_IP(
-			DEBUG_LEVEL_ERROR,
-			("hws_ddr3_tip_init_controller failure\n"));
-	}
-
-	/* calculate the round trip delay for Write Leveling */
-	table_ptr = static_config[dev_num].board_trace_arr;
-	CHECK_STATUS(ddr3_tip_static_round_trip_arr_build
-		     (dev_num, table_ptr, 1,
-		      wl_total_round_trip_delay_arr));
-	/* calculate the round trip delay  for Read Leveling */
-	CHECK_STATUS(ddr3_tip_static_round_trip_arr_build
-		     (dev_num, table_ptr, 0,
-		      rl_total_round_trip_delay_arr));
-
-	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		/* check if the interface is enabled */
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-		/*
-		 * Static frequency is defined according to init-frequency
-		 * (not target)
-		 */
-		DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
-					 ("Static IF %d freq %d\n",
-					  if_id, freq));
-		CHECK_STATUS(ddr3_tip_write_leveling_static_config
-			     (dev_num, if_id, freq,
-			      wl_total_round_trip_delay_arr));
-		CHECK_STATUS(ddr3_tip_read_leveling_static_config
-			     (dev_num, if_id, freq,
-			      rl_total_round_trip_delay_arr));
-	}
-
-	return MV_OK;
-}
-
-/*
- * Init controller for static flow
- */
-int ddr3_tip_static_init_controller(u32 dev_num)
-{
-	u32 index_cnt = 0;
-
-	DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
-				 ("ddr3_tip_static_init_controller\n"));
-	while (static_init_controller_config[dev_num][index_cnt].reg_addr !=
-	       0) {
-		CHECK_STATUS(ddr3_tip_if_write
-			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      static_init_controller_config[dev_num][index_cnt].
-			      reg_addr,
-			      static_init_controller_config[dev_num][index_cnt].
-			      reg_data,
-			      static_init_controller_config[dev_num][index_cnt].
-			      reg_mask));
-
-		DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
-					 ("Init_controller index_cnt %d\n",
-					  index_cnt));
-		index_cnt++;
-	}
-
-	return MV_OK;
-}
-
-int ddr3_tip_static_phy_init_controller(u32 dev_num)
-{
-	DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
-				 ("Phy Init Controller 2\n"));
-	CHECK_STATUS(ddr3_tip_bus_write
-		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0xa4,
-		      0x3dfe));
-
-	DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
-				 ("Phy Init Controller 3\n"));
-	CHECK_STATUS(ddr3_tip_bus_write
-		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0xa6,
-		      0xcb2));
-
-	DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
-				 ("Phy Init Controller 4\n"));
-	CHECK_STATUS(ddr3_tip_bus_write
-		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0xa9,
-		      0));
-
-	DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
-				 ("Static Receiver Calibration\n"));
-	CHECK_STATUS(ddr3_tip_bus_write
-		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0xd0,
-		      0x1f));
-
-	DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
-				 ("Static V-REF Calibration\n"));
-	CHECK_STATUS(ddr3_tip_bus_write
-		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0xa8,
-		      0x434));
-
-	return MV_OK;
-}
-#endif
 
 /*
  * Configure phy (called by static init controller) for static flow
-- 
2.16.2

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH v2 4/6] ARM: mvebu: a38x: sync ddr training code with upstream
  2018-04-09 10:12 [U-Boot] [PATCH v2 0/6] ARM: mvebu: a38x: updates to ddr training code Chris Packham
                   ` (2 preceding siblings ...)
  2018-04-09 10:12 ` [U-Boot] [PATCH v2 3/6] ARM: mvebu: a38x: remove some unused code Chris Packham
@ 2018-04-09 10:12 ` Chris Packham
  2018-04-09 10:12 ` [U-Boot] [PATCH v2 5/6] ARM: mvebu: a38x: restore support for setting timing Chris Packham
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Chris Packham @ 2018-04-09 10:12 UTC (permalink / raw)
  To: u-boot

This syncs drivers/ddr/marvell/a38x/ with the mv_ddr-armada-17.10 branch
of https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git.

The upstream code is incorporated omitting the ddr4 and apn806 and
folding the nested a38x directory up one level. After that a
semi-automated step is used to drop unused features with unifdef

  find drivers/ddr/marvell/a38x/ -name '*.[ch]' | \
    xargs unifdef -m -UMV_DDR -UMV_DDR_ATF -UCONFIG_DDR4 \
		-UCONFIG_APN806 -UCONFIG_MC_STATIC \
		-UCONFIG_MC_STATIC_PRINT -UCONFIG_PHY_STATIC \
		-UCONFIG_64BIT

INTER_REGS_BASE is updated to be defined as SOC_REGS_PHY_BASE.

Some now empty files are removed and the ternary license is replaced
with a SPDX GPL-2.0+ identifier.

Signed-off-by: Chris Packham <judge.packham@gmail.com>
---

Changes in v2: New

 board/CZ.NIC/turris_omnia/turris_omnia.c           |   36 +-
 board/Marvell/db-88f6820-amc/db-88f6820-amc.c      |   20 +-
 board/Marvell/db-88f6820-gp/db-88f6820-gp.c        |   20 +-
 board/gdsys/a38x/controlcenterdc.c                 |   21 +-
 board/solidrun/clearfog/clearfog.c                 |   20 +-
 drivers/ddr/marvell/a38x/Makefile                  |   10 +-
 drivers/ddr/marvell/a38x/ddr3_a38x.c               |  686 ---------
 drivers/ddr/marvell/a38x/ddr3_a38x.h               |   93 --
 drivers/ddr/marvell/a38x/ddr3_a38x_topology.h      |   22 -
 drivers/ddr/marvell/a38x/ddr3_a38x_training.c      |   40 -
 drivers/ddr/marvell/a38x/ddr3_debug.c              |  733 ++++++----
 drivers/ddr/marvell/a38x/ddr3_hws_hw_training.c    |  148 --
 drivers/ddr/marvell/a38x/ddr3_hws_hw_training.h    |   49 -
 .../ddr/marvell/a38x/ddr3_hws_hw_training_def.h    |  462 -------
 drivers/ddr/marvell/a38x/ddr3_hws_sil_training.h   |   17 -
 drivers/ddr/marvell/a38x/ddr3_init.c               |  745 ++--------
 drivers/ddr/marvell/a38x/ddr3_init.h               |  299 +---
 drivers/ddr/marvell/a38x/ddr3_logging_def.h        |   10 +-
 drivers/ddr/marvell/a38x/ddr3_patterns_64bit.h     |    1 +
 drivers/ddr/marvell/a38x/ddr3_topology_def.h       |    6 +-
 drivers/ddr/marvell/a38x/ddr3_training.c           | 1450 +++++++++++--------
 drivers/ddr/marvell/a38x/ddr3_training_bist.c      |  548 ++++++--
 .../marvell/a38x/ddr3_training_centralization.c    |  108 +-
 drivers/ddr/marvell/a38x/ddr3_training_db.c        |  267 +++-
 drivers/ddr/marvell/a38x/ddr3_training_hw_algo.c   |   98 +-
 drivers/ddr/marvell/a38x/ddr3_training_ip.h        |   19 +-
 drivers/ddr/marvell/a38x/ddr3_training_ip_bist.h   |    6 +-
 drivers/ddr/marvell/a38x/ddr3_training_ip_db.h     |   71 +-
 drivers/ddr/marvell/a38x/ddr3_training_ip_def.h    |   34 +-
 drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c | 1134 +++++++++------
 drivers/ddr/marvell/a38x/ddr3_training_ip_engine.h |    9 +-
 drivers/ddr/marvell/a38x/ddr3_training_ip_flow.h   |  305 +---
 drivers/ddr/marvell/a38x/ddr3_training_ip_prv_if.h |   17 +-
 drivers/ddr/marvell/a38x/ddr3_training_ip_static.h |   31 -
 drivers/ddr/marvell/a38x/ddr3_training_leveling.c  | 1347 ++++++++++--------
 drivers/ddr/marvell/a38x/ddr3_training_leveling.h  |    2 +-
 drivers/ddr/marvell/a38x/ddr3_training_pbs.c       |  201 +--
 drivers/ddr/marvell/a38x/ddr3_training_static.c    |  101 --
 drivers/ddr/marvell/a38x/ddr_ml_wrapper.h          |  149 ++
 drivers/ddr/marvell/a38x/ddr_topology_def.h        |   85 +-
 drivers/ddr/marvell/a38x/mv_ddr_build_message.c    |    1 +
 drivers/ddr/marvell/a38x/mv_ddr_common.c           |   48 +
 drivers/ddr/marvell/a38x/mv_ddr_common.h           |   21 +
 drivers/ddr/marvell/a38x/mv_ddr_plat.c             | 1456 ++++++++++++++++++++
 drivers/ddr/marvell/a38x/mv_ddr_plat.h             |  236 ++++
 drivers/ddr/marvell/a38x/mv_ddr_regs.h             |  447 ++++++
 drivers/ddr/marvell/a38x/mv_ddr_spd.c              |  378 +++++
 drivers/ddr/marvell/a38x/mv_ddr_spd.h              |  290 ++++
 drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.c      |  103 ++
 drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.h      |  118 ++
 drivers/ddr/marvell/a38x/mv_ddr_topology.c         |  198 +++
 drivers/ddr/marvell/a38x/mv_ddr_topology.h         |  124 ++
 drivers/ddr/marvell/a38x/seq_exec.h                |   65 +
 drivers/ddr/marvell/a38x/silicon_if.h              |   17 -
 drivers/ddr/marvell/a38x/xor.c                     |  184 ++-
 drivers/ddr/marvell/a38x/xor.h                     |    3 +-
 56 files changed, 7958 insertions(+), 5151 deletions(-)
 delete mode 100644 drivers/ddr/marvell/a38x/ddr3_a38x.c
 delete mode 100644 drivers/ddr/marvell/a38x/ddr3_a38x.h
 delete mode 100644 drivers/ddr/marvell/a38x/ddr3_a38x_topology.h
 delete mode 100644 drivers/ddr/marvell/a38x/ddr3_a38x_training.c
 delete mode 100644 drivers/ddr/marvell/a38x/ddr3_hws_hw_training.c
 delete mode 100644 drivers/ddr/marvell/a38x/ddr3_hws_hw_training.h
 delete mode 100644 drivers/ddr/marvell/a38x/ddr3_hws_hw_training_def.h
 delete mode 100644 drivers/ddr/marvell/a38x/ddr3_hws_sil_training.h
 delete mode 100644 drivers/ddr/marvell/a38x/ddr3_training_ip_static.h
 delete mode 100644 drivers/ddr/marvell/a38x/ddr3_training_static.c
 create mode 100644 drivers/ddr/marvell/a38x/ddr_ml_wrapper.h
 create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_build_message.c
 create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_common.c
 create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_common.h
 create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_plat.c
 create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_plat.h
 create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_regs.h
 create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_spd.c
 create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_spd.h
 create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.c
 create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.h
 create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_topology.c
 create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_topology.h
 create mode 100644 drivers/ddr/marvell/a38x/seq_exec.h
 delete mode 100644 drivers/ddr/marvell/a38x/silicon_if.h

diff --git a/board/CZ.NIC/turris_omnia/turris_omnia.c b/board/CZ.NIC/turris_omnia/turris_omnia.c
index b03c0a3714b1..9477a802acde 100644
--- a/board/CZ.NIC/turris_omnia/turris_omnia.c
+++ b/board/CZ.NIC/turris_omnia/turris_omnia.c
@@ -27,7 +27,7 @@
 # include <wdt.h>
 #endif
 
-#include "../drivers/ddr/marvell/a38x/ddr3_a38x_topology.h"
+#include "../drivers/ddr/marvell/a38x/ddr3_init.h"
 #include <../serdes/a38x/high_speed_env_spec.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -200,7 +200,8 @@ static bool omnia_read_eeprom(struct omnia_eeprom *oep)
  * be used by the DDR3 init code in the SPL U-Boot version to configure
  * the DDR3 controller.
  */
-static struct hws_topology_map board_topology_map_1g = {
+static struct mv_ddr_topology_map board_topology_map_1g = {
+	DEBUG_LEVEL_ERROR,
 	0x1, /* active interfaces */
 	/* cs_mask, mirror, dqs_swap, ck_swap X PUPs */
 	{ { { {0x1, 0, 0, 0},
@@ -209,17 +210,19 @@ static struct hws_topology_map board_topology_map_1g = {
 	      {0x1, 0, 0, 0},
 	      {0x1, 0, 0, 0} },
 	    SPEED_BIN_DDR_1600K,	/* speed_bin */
-	    BUS_WIDTH_16,		/* memory_width */
-	    MEM_4G,			/* mem_size */
+	    MV_DDR_DEV_WIDTH_16BIT,	/* memory_width */
+	    MV_DDR_DIE_CAP_4GBIT,			/* mem_size */
 	    DDR_FREQ_800,		/* frequency */
 	    0, 0,			/* cas_wl cas_l */
-	    HWS_TEMP_NORMAL,		/* temperature */
-	    HWS_TIM_2T} },		/* timing (force 2t) */
-	5,				/* Num Of Bus Per Interface*/
-	BUS_MASK_32BIT			/* Busses mask */
+	    MV_DDR_TEMP_NORMAL} },	/* temperature */
+	BUS_MASK_32BIT,			/* Busses mask */
+	MV_DDR_CFG_DEFAULT,		/* ddr configuration data source */
+	{ {0} },			/* raw spd data */
+	{0}				/* timing parameters */
 };
 
-static struct hws_topology_map board_topology_map_2g = {
+static struct mv_ddr_topology_map board_topology_map_2g = {
+	DEBUG_LEVEL_ERROR,
 	0x1, /* active interfaces */
 	/* cs_mask, mirror, dqs_swap, ck_swap X PUPs */
 	{ { { {0x1, 0, 0, 0},
@@ -228,17 +231,18 @@ static struct hws_topology_map board_topology_map_2g = {
 	      {0x1, 0, 0, 0},
 	      {0x1, 0, 0, 0} },
 	    SPEED_BIN_DDR_1600K,	/* speed_bin */
-	    BUS_WIDTH_16,		/* memory_width */
-	    MEM_8G,			/* mem_size */
+	    MV_DDR_DEV_WIDTH_16BIT,	/* memory_width */
+	    MV_DDR_DIE_CAP_8GBIT,			/* mem_size */
 	    DDR_FREQ_800,		/* frequency */
 	    0, 0,			/* cas_wl cas_l */
-	    HWS_TEMP_NORMAL,		/* temperature */
-	    HWS_TIM_2T} },		/* timing (force 2t) */
-	5,				/* Num Of Bus Per Interface*/
-	BUS_MASK_32BIT			/* Busses mask */
+	    MV_DDR_TEMP_NORMAL} },	/* temperature */
+	BUS_MASK_32BIT,			/* Busses mask */
+	MV_DDR_CFG_DEFAULT,		/* ddr configuration data source */
+	{ {0} },			/* raw spd data */
+	{0}				/* timing parameters */
 };
 
-struct hws_topology_map *ddr3_get_topology_map(void)
+struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
 {
 	static int mem = 0;
 	struct omnia_eeprom oep;
diff --git a/board/Marvell/db-88f6820-amc/db-88f6820-amc.c b/board/Marvell/db-88f6820-amc/db-88f6820-amc.c
index 7db0095f75ef..2a092cb80418 100644
--- a/board/Marvell/db-88f6820-amc/db-88f6820-amc.c
+++ b/board/Marvell/db-88f6820-amc/db-88f6820-amc.c
@@ -12,7 +12,7 @@
 #include <asm/arch/cpu.h>
 #include <asm/arch/soc.h>
 
-#include "../drivers/ddr/marvell/a38x/ddr3_a38x_topology.h"
+#include "../drivers/ddr/marvell/a38x/ddr3_init.h"
 #include <../serdes/a38x/high_speed_env_spec.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -56,7 +56,8 @@ int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count)
  * be used by the DDR3 init code in the SPL U-Boot version to configure
  * the DDR3 controller.
  */
-static struct hws_topology_map board_topology_map = {
+static struct mv_ddr_topology_map board_topology_map = {
+	DEBUG_LEVEL_ERROR,
 	0x1, /* active interfaces */
 	/* cs_mask, mirror, dqs_swap, ck_swap X PUPs */
 	{ { { {0x1, 0, 0, 0},
@@ -65,17 +66,18 @@ static struct hws_topology_map board_topology_map = {
 	      {0x1, 0, 0, 0},
 	      {0x1, 0, 0, 0} },
 	    SPEED_BIN_DDR_1866L,	/* speed_bin */
-	    BUS_WIDTH_8,		/* memory_width */
-	    MEM_2G,			/* mem_size */
+	    MV_DDR_DEV_WIDTH_8BIT,	/* memory_width */
+	    MV_DDR_DIE_CAP_2GBIT,	/* mem_size */
 	    DDR_FREQ_800,		/* frequency */
 	    0, 0,			/* cas_wl cas_l */
-	    HWS_TEMP_LOW,		/* temperature */
-	    HWS_TIM_DEFAULT} },		/* timing */
-	5,				/* Num Of Bus Per Interface*/
-	BUS_MASK_32BIT			/* Busses mask */
+	    MV_DDR_TEMP_LOW} },		/* temperature */
+	BUS_MASK_32BIT,			/* Busses mask */
+	MV_DDR_CFG_DEFAULT,		/* ddr configuration data source */
+	{ {0} },			/* raw spd data */
+	{0}				/* timing parameters */
 };
 
-struct hws_topology_map *ddr3_get_topology_map(void)
+struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
 {
 	/* Return the board topology as defined in the board code */
 	return &board_topology_map;
diff --git a/board/Marvell/db-88f6820-gp/db-88f6820-gp.c b/board/Marvell/db-88f6820-gp/db-88f6820-gp.c
index b95cd1d4aab5..e3b6f2d8a7e6 100644
--- a/board/Marvell/db-88f6820-gp/db-88f6820-gp.c
+++ b/board/Marvell/db-88f6820-gp/db-88f6820-gp.c
@@ -12,7 +12,7 @@
 #include <asm/arch/cpu.h>
 #include <asm/arch/soc.h>
 
-#include "../drivers/ddr/marvell/a38x/ddr3_a38x_topology.h"
+#include "../drivers/ddr/marvell/a38x/ddr3_init.h"
 #include <../serdes/a38x/high_speed_env_spec.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -77,7 +77,8 @@ int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count)
  * be used by the DDR3 init code in the SPL U-Boot version to configure
  * the DDR3 controller.
  */
-static struct hws_topology_map board_topology_map = {
+static struct mv_ddr_topology_map board_topology_map = {
+	DEBUG_LEVEL_ERROR,
 	0x1, /* active interfaces */
 	/* cs_mask, mirror, dqs_swap, ck_swap X PUPs */
 	{ { { {0x1, 0, 0, 0},
@@ -86,17 +87,18 @@ static struct hws_topology_map board_topology_map = {
 	      {0x1, 0, 0, 0},
 	      {0x1, 0, 0, 0} },
 	    SPEED_BIN_DDR_1866L,	/* speed_bin */
-	    BUS_WIDTH_8,		/* memory_width */
-	    MEM_4G,			/* mem_size */
+	    MV_DDR_DEV_WIDTH_8BIT,	/* memory_width */
+	    MV_DDR_DIE_CAP_4GBIT,	/* mem_size */
 	    DDR_FREQ_800,		/* frequency */
 	    0, 0,			/* cas_wl cas_l */
-	    HWS_TEMP_LOW,		/* temperature */
-	    HWS_TIM_DEFAULT} },		/* timing */
-	5,				/* Num Of Bus Per Interface*/
-	BUS_MASK_32BIT			/* Busses mask */
+	    MV_DDR_TEMP_LOW} },		/* temperature */
+	BUS_MASK_32BIT,			/* Busses mask */
+	MV_DDR_CFG_DEFAULT,		/* ddr configuration data source */
+	{ {0} },			/* raw spd data */
+	{0}				/* timing parameters */
 };
 
-struct hws_topology_map *ddr3_get_topology_map(void)
+struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
 {
 	/* Return the board topology as defined in the board code */
 	return &board_topology_map;
diff --git a/board/gdsys/a38x/controlcenterdc.c b/board/gdsys/a38x/controlcenterdc.c
index 3d74a6dfb897..1b3b881c3996 100644
--- a/board/gdsys/a38x/controlcenterdc.c
+++ b/board/gdsys/a38x/controlcenterdc.c
@@ -13,7 +13,7 @@
 #include <asm/arch/cpu.h>
 #include <asm-generic/gpio.h>
 
-#include "../drivers/ddr/marvell/a38x/ddr3_a38x_topology.h"
+#include "../drivers/ddr/marvell/a38x/ddr3_init.h"
 #include "../arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.h"
 
 #include "keyprogram.h"
@@ -40,7 +40,8 @@ DECLARE_GLOBAL_DATA_PTR;
  * be used by the DDR3 init code in the SPL U-Boot version to configure
  * the DDR3 controller.
  */
-static struct hws_topology_map ddr_topology_map = {
+static struct mv_ddr_topology_map ddr_topology_map = {
+	DEBUG_LEVEL_ERROR,
 	0x1, /* active interfaces */
 	/* cs_mask, mirror, dqs_swap, ck_swap X PUPs */
 	{ { { {0x1, 0, 0, 0},
@@ -49,14 +50,16 @@ static struct hws_topology_map ddr_topology_map = {
 	      {0x1, 0, 0, 0},
 	      {0x1, 0, 0, 0} },
 	    SPEED_BIN_DDR_1600K,	/* speed_bin */
-	    BUS_WIDTH_16,		/* memory_width */
-	    MEM_4G,			/* mem_size */
+	    MV_DDR_DEV_WIDTH_16BIT,	/* memory_width */
+	    MV_DDR_DIE_CAP_4GBIT,	/* mem_size */
 	    DDR_FREQ_533,		/* frequency */
 	    0, 0,			/* cas_wl cas_l */
-	    HWS_TEMP_LOW,		/* temperature */
-	    HWS_TIM_DEFAULT} },		/* timing */
-	5,				/* Num Of Bus Per Interface*/
-	BUS_MASK_32BIT			/* Busses mask */
+	    MV_DDR_TEMP_LOW} },		/* temperature */
+	BUS_MASK_32BIT,			/* Busses mask */
+	MV_DDR_CFG_DEFAULT,		/* ddr configuration data source */
+	{ {0} },			/* raw spd data */
+	{0}				/* timing parameters */
+
 };
 
 static struct serdes_map serdes_topology_map[] = {
@@ -122,7 +125,7 @@ void board_pex_config(void)
 #endif
 }
 
-struct hws_topology_map *ddr3_get_topology_map(void)
+struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
 {
 	return &ddr_topology_map;
 }
diff --git a/board/solidrun/clearfog/clearfog.c b/board/solidrun/clearfog/clearfog.c
index 1472e9793e5f..75eb59ae3ee3 100644
--- a/board/solidrun/clearfog/clearfog.c
+++ b/board/solidrun/clearfog/clearfog.c
@@ -12,7 +12,7 @@
 #include <asm/arch/cpu.h>
 #include <asm/arch/soc.h>
 
-#include "../drivers/ddr/marvell/a38x/ddr3_a38x_topology.h"
+#include "../drivers/ddr/marvell/a38x/ddr3_init.h"
 #include <../serdes/a38x/high_speed_env_spec.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -70,7 +70,8 @@ int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count)
  * be used by the DDR3 init code in the SPL U-Boot version to configure
  * the DDR3 controller.
  */
-static struct hws_topology_map board_topology_map = {
+static struct mv_ddr_topology_map board_topology_map = {
+	DEBUG_LEVEL_ERROR,
 	0x1, /* active interfaces */
 	/* cs_mask, mirror, dqs_swap, ck_swap X PUPs */
 	{ { { {0x1, 0, 0, 0},
@@ -79,17 +80,18 @@ static struct hws_topology_map board_topology_map = {
 	      {0x1, 0, 0, 0},
 	      {0x1, 0, 0, 0} },
 	    SPEED_BIN_DDR_1600K,	/* speed_bin */
-	    BUS_WIDTH_16,		/* memory_width */
-	    MEM_4G,			/* mem_size */
+	    MV_DDR_DEV_WIDTH_16BIT,	/* memory_width */
+	    MV_DDR_DIE_CAP_4GBIT,	/* mem_size */
 	    DDR_FREQ_800,		/* frequency */
 	    0, 0,			/* cas_wl cas_l */
-	    HWS_TEMP_LOW,		/* temperature */
-	    HWS_TIM_DEFAULT} },		/* timing */
-	5,				/* Num Of Bus Per Interface*/
-	BUS_MASK_32BIT			/* Busses mask */
+	    MV_DDR_TEMP_LOW} },		/* temperature */
+	BUS_MASK_32BIT,			/* Busses mask */
+	MV_DDR_CFG_DEFAULT,		/* ddr configuration data source */
+	{ {0} },			/* raw spd data */
+	{0}				/* timing parameters */
 };
 
-struct hws_topology_map *ddr3_get_topology_map(void)
+struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
 {
 	/* Return the board topology as defined in the board code */
 	return &board_topology_map;
diff --git a/drivers/ddr/marvell/a38x/Makefile b/drivers/ddr/marvell/a38x/Makefile
index bf6ea4945f03..aadfb767e30d 100644
--- a/drivers/ddr/marvell/a38x/Makefile
+++ b/drivers/ddr/marvell/a38x/Makefile
@@ -2,10 +2,9 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
-obj-$(CONFIG_SPL_BUILD) += ddr3_a38x.o
-obj-$(CONFIG_SPL_BUILD) += ddr3_a38x_training.o
+obj-$(CONFIG_SPL_BUILD) += mv_ddr_plat.o
+obj-$(CONFIG_SPL_BUILD) += mv_ddr_sys_env_lib.o
 obj-$(CONFIG_SPL_BUILD) += ddr3_debug.o
-obj-$(CONFIG_SPL_BUILD) += ddr3_hws_hw_training.o
 obj-$(CONFIG_SPL_BUILD) += ddr3_init.o
 obj-$(CONFIG_SPL_BUILD) += ddr3_training.o
 obj-$(CONFIG_SPL_BUILD) += ddr3_training_bist.o
@@ -15,5 +14,8 @@ obj-$(CONFIG_SPL_BUILD) += ddr3_training_hw_algo.o
 obj-$(CONFIG_SPL_BUILD) += ddr3_training_ip_engine.o
 obj-$(CONFIG_SPL_BUILD) += ddr3_training_leveling.o
 obj-$(CONFIG_SPL_BUILD) += ddr3_training_pbs.o
-obj-$(CONFIG_SPL_BUILD) += ddr3_training_static.o
+obj-$(CONFIG_SPL_BUILD) += mv_ddr_build_message.o
+obj-$(CONFIG_SPL_BUILD) += mv_ddr_common.o
+obj-$(CONFIG_SPL_BUILD) += mv_ddr_spd.o
+obj-$(CONFIG_SPL_BUILD) += mv_ddr_topology.o
 obj-$(CONFIG_SPL_BUILD) += xor.o
diff --git a/drivers/ddr/marvell/a38x/ddr3_a38x.c b/drivers/ddr/marvell/a38x/ddr3_a38x.c
deleted file mode 100644
index 22390325003d..000000000000
--- a/drivers/ddr/marvell/a38x/ddr3_a38x.c
+++ /dev/null
@@ -1,686 +0,0 @@
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- *
- * SPDX-License-Identifier:	GPL-2.0
- */
-
-#include <common.h>
-#include <i2c.h>
-#include <spl.h>
-#include <asm/io.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/soc.h>
-
-#include "ddr3_init.h"
-
-#define A38X_NUMBER_OF_INTERFACES	5
-
-#define SAR_DEV_ID_OFFS			27
-#define SAR_DEV_ID_MASK			0x7
-
-/* Termal Sensor Registers */
-#define TSEN_STATE_REG			0xe4070
-#define TSEN_STATE_OFFSET		31
-#define TSEN_STATE_MASK			(0x1 << TSEN_STATE_OFFSET)
-#define TSEN_CONF_REG			0xe4074
-#define TSEN_CONF_RST_OFFSET		8
-#define TSEN_CONF_RST_MASK		(0x1 << TSEN_CONF_RST_OFFSET)
-#define TSEN_STATUS_REG			0xe4078
-#define TSEN_STATUS_READOUT_VALID_OFFSET	10
-#define TSEN_STATUS_READOUT_VALID_MASK	(0x1 <<				\
-					 TSEN_STATUS_READOUT_VALID_OFFSET)
-#define TSEN_STATUS_TEMP_OUT_OFFSET	0
-#define TSEN_STATUS_TEMP_OUT_MASK	(0x3ff << TSEN_STATUS_TEMP_OUT_OFFSET)
-
-static struct dfx_access interface_map[] = {
-	/* Pipe	Client */
-	{ 0, 17 },
-	{ 1, 7 },
-	{ 1, 11 },
-	{ 0, 3 },
-	{ 1, 25 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 },
-	{ 0, 0 }
-};
-
-/* This array hold the board round trip delay (DQ and CK) per <interface,bus> */
-struct trip_delay_element a38x_board_round_trip_delay_array[] = {
-	/* 1st board */
-	/* Interface bus DQS-delay CK-delay */
-	{ 3952, 5060 },
-	{ 3192, 4493 },
-	{ 4785, 6677 },
-	{ 3413, 7267 },
-	{ 4282, 6086 },	/* ECC PUP */
-	{ 3952, 5134 },
-	{ 3192, 4567 },
-	{ 4785, 6751 },
-	{ 3413, 7341 },
-	{ 4282, 6160 },	/* ECC PUP */
-
-	/* 2nd board */
-	/* Interface bus DQS-delay CK-delay */
-	{ 3952, 5060 },
-	{ 3192, 4493 },
-	{ 4785, 6677 },
-	{ 3413, 7267 },
-	{ 4282, 6086 },	/* ECC PUP */
-	{ 3952, 5134 },
-	{ 3192, 4567 },
-	{ 4785, 6751 },
-	{ 3413, 7341 },
-	{ 4282, 6160 }	/* ECC PUP */
-};
-
-
-static u8 a38x_bw_per_freq[DDR_FREQ_LIMIT] = {
-	0x3,			/* DDR_FREQ_100 */
-	0x4,			/* DDR_FREQ_400 */
-	0x4,			/* DDR_FREQ_533 */
-	0x5,			/* DDR_FREQ_667 */
-	0x5,			/* DDR_FREQ_800 */
-	0x5,			/* DDR_FREQ_933 */
-	0x5,			/* DDR_FREQ_1066 */
-	0x3,			/* DDR_FREQ_311 */
-	0x3,			/* DDR_FREQ_333 */
-	0x4,			/* DDR_FREQ_467 */
-	0x5,			/* DDR_FREQ_850 */
-	0x5,			/* DDR_FREQ_600 */
-	0x3,			/* DDR_FREQ_300 */
-	0x5,			/* DDR_FREQ_900 */
-	0x3,			/* DDR_FREQ_360 */
-	0x5			/* DDR_FREQ_1000 */
-};
-
-static u8 a38x_rate_per_freq[DDR_FREQ_LIMIT] = {
-	 /*TBD*/ 0x1,		/* DDR_FREQ_100 */
-	0x2,			/* DDR_FREQ_400 */
-	0x2,			/* DDR_FREQ_533 */
-	0x2,			/* DDR_FREQ_667 */
-	0x2,			/* DDR_FREQ_800 */
-	0x3,			/* DDR_FREQ_933 */
-	0x3,			/* DDR_FREQ_1066 */
-	0x1,			/* DDR_FREQ_311 */
-	0x1,			/* DDR_FREQ_333 */
-	0x2,			/* DDR_FREQ_467 */
-	0x2,			/* DDR_FREQ_850 */
-	0x2,			/* DDR_FREQ_600 */
-	0x1,			/* DDR_FREQ_300 */
-	0x2,			/* DDR_FREQ_900 */
-	0x1,			/* DDR_FREQ_360 */
-	0x2			/* DDR_FREQ_1000 */
-};
-
-static u16 a38x_vco_freq_per_sar[] = {
-	666,			/* 0 */
-	1332,
-	800,
-	1600,
-	1066,
-	2132,
-	1200,
-	2400,
-	1332,
-	1332,
-	1500,
-	1500,
-	1600,			/* 12 */
-	1600,
-	1700,
-	1700,
-	1866,
-	1866,
-	1800,			/* 18 */
-	2000,
-	2000,
-	4000,
-	2132,
-	2132,
-	2300,
-	2300,
-	2400,
-	2400,
-	2500,
-	2500,
-	800
-};
-
-u32 pipe_multicast_mask;
-
-u32 dq_bit_map_2_phy_pin[] = {
-	1, 0, 2, 6, 9, 8, 3, 7,	/* 0 */
-	8, 9, 1, 7, 2, 6, 3, 0,	/* 1 */
-	3, 9, 7, 8, 1, 0, 2, 6,	/* 2 */
-	1, 0, 6, 2, 8, 3, 7, 9,	/* 3 */
-	0, 1, 2, 9, 7, 8, 3, 6,	/* 4 */
-};
-
-static int ddr3_tip_a38x_set_divider(u8 dev_num, u32 if_id,
-				     enum hws_ddr_freq freq);
-
-/*
- * Read temperature TJ value
- */
-u32 ddr3_ctrl_get_junc_temp(u8 dev_num)
-{
-	int reg = 0;
-
-	/* Initiates TSEN hardware reset once */
-	if ((reg_read(TSEN_CONF_REG) & TSEN_CONF_RST_MASK) == 0)
-		reg_bit_set(TSEN_CONF_REG, TSEN_CONF_RST_MASK);
-	mdelay(10);
-
-	/* Check if the readout field is valid */
-	if ((reg_read(TSEN_STATUS_REG) & TSEN_STATUS_READOUT_VALID_MASK) == 0) {
-		printf("%s: TSEN not ready\n", __func__);
-		return 0;
-	}
-
-	reg = reg_read(TSEN_STATUS_REG);
-	reg = (reg & TSEN_STATUS_TEMP_OUT_MASK) >> TSEN_STATUS_TEMP_OUT_OFFSET;
-
-	return ((((10000 * reg) / 21445) * 1000) - 272674) / 1000;
-}
-
-/*
- * Name:     ddr3_tip_a38x_get_freq_config.
- * Desc:
- * Args:
- * Notes:
- * Returns:  MV_OK if success, other error code if fail.
- */
-int ddr3_tip_a38x_get_freq_config(u8 dev_num, enum hws_ddr_freq freq,
-				  struct hws_tip_freq_config_info
-				  *freq_config_info)
-{
-	if (a38x_bw_per_freq[freq] == 0xff)
-		return MV_NOT_SUPPORTED;
-
-	if (freq_config_info == NULL)
-		return MV_BAD_PARAM;
-
-	freq_config_info->bw_per_freq = a38x_bw_per_freq[freq];
-	freq_config_info->rate_per_freq = a38x_rate_per_freq[freq];
-	freq_config_info->is_supported = 1;
-
-	return MV_OK;
-}
-
-/*
- * Name:     ddr3_tip_a38x_pipe_enable.
- * Desc:
- * Args:
- * Notes:
- * Returns:  MV_OK if success, other error code if fail.
- */
-int ddr3_tip_a38x_pipe_enable(u8 dev_num, enum hws_access_type interface_access,
-			      u32 if_id, int enable)
-{
-	u32 data_value, pipe_enable_mask = 0;
-
-	if (enable == 0) {
-		pipe_enable_mask = 0;
-	} else {
-		if (interface_access == ACCESS_TYPE_MULTICAST)
-			pipe_enable_mask = pipe_multicast_mask;
-		else
-			pipe_enable_mask = (1 << interface_map[if_id].pipe);
-	}
-
-	CHECK_STATUS(ddr3_tip_reg_read
-		     (dev_num, PIPE_ENABLE_ADDR, &data_value, MASK_ALL_BITS));
-	data_value = (data_value & (~0xff)) | pipe_enable_mask;
-	CHECK_STATUS(ddr3_tip_reg_write(dev_num, PIPE_ENABLE_ADDR, data_value));
-
-	return MV_OK;
-}
-
-/*
- * Name:     ddr3_tip_a38x_if_write.
- * Desc:
- * Args:
- * Notes:
- * Returns:  MV_OK if success, other error code if fail.
- */
-int ddr3_tip_a38x_if_write(u8 dev_num, enum hws_access_type interface_access,
-			   u32 if_id, u32 reg_addr, u32 data_value,
-			   u32 mask)
-{
-	u32 ui_data_read;
-
-	if (mask != MASK_ALL_BITS) {
-		CHECK_STATUS(ddr3_tip_a38x_if_read
-			     (dev_num, ACCESS_TYPE_UNICAST, if_id, reg_addr,
-			      &ui_data_read, MASK_ALL_BITS));
-		data_value = (ui_data_read & (~mask)) | (data_value & mask);
-	}
-
-	reg_write(reg_addr, data_value);
-
-	return MV_OK;
-}
-
-/*
- * Name:     ddr3_tip_a38x_if_read.
- * Desc:
- * Args:
- * Notes:
- * Returns:  MV_OK if success, other error code if fail.
- */
-int ddr3_tip_a38x_if_read(u8 dev_num, enum hws_access_type interface_access,
-			  u32 if_id, u32 reg_addr, u32 *data, u32 mask)
-{
-	*data = reg_read(reg_addr) & mask;
-
-	return MV_OK;
-}
-
-/*
- * Name:     ddr3_tip_a38x_select_ddr_controller.
- * Desc:     Enable/Disable access to Marvell's server.
- * Args:     dev_num     - device number
- *           enable        - whether to enable or disable the server
- * Notes:
- * Returns:  MV_OK if success, other error code if fail.
- */
-int ddr3_tip_a38x_select_ddr_controller(u8 dev_num, int enable)
-{
-	u32 reg;
-
-	reg = reg_read(CS_ENABLE_REG);
-
-	if (enable)
-		reg |= (1 << 6);
-	else
-		reg &= ~(1 << 6);
-
-	reg_write(CS_ENABLE_REG, reg);
-
-	return MV_OK;
-}
-
-/*
- * Name:     ddr3_tip_init_a38x_silicon.
- * Desc:     init Training SW DB.
- * Args:
- * Notes:
- * Returns:  MV_OK if success, other error code if fail.
- */
-static int ddr3_tip_init_a38x_silicon(u32 dev_num, u32 board_id)
-{
-	struct hws_tip_config_func_db config_func;
-	enum hws_ddr_freq ddr_freq;
-	int status;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
-
-	/* new read leveling version */
-	config_func.tip_dunit_read_func = ddr3_tip_a38x_if_read;
-	config_func.tip_dunit_write_func = ddr3_tip_a38x_if_write;
-	config_func.tip_dunit_mux_select_func =
-		ddr3_tip_a38x_select_ddr_controller;
-	config_func.tip_get_freq_config_info_func =
-		ddr3_tip_a38x_get_freq_config;
-	config_func.tip_set_freq_divider_func = ddr3_tip_a38x_set_divider;
-	config_func.tip_get_device_info_func = ddr3_tip_a38x_get_device_info;
-	config_func.tip_get_temperature = ddr3_ctrl_get_junc_temp;
-
-	ddr3_tip_init_config_func(dev_num, &config_func);
-
-	ddr3_tip_register_dq_table(dev_num, dq_bit_map_2_phy_pin);
-
-	status = ddr3_tip_a38x_get_init_freq(dev_num, &ddr_freq);
-	if (MV_OK != status) {
-		DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR,
-				      ("DDR3 silicon get target frequency - FAILED 0x%x\n",
-				       status));
-		return status;
-	}
-
-	rl_version = 1;
-	mask_tune_func = (SET_LOW_FREQ_MASK_BIT |
-			  LOAD_PATTERN_MASK_BIT |
-			  SET_MEDIUM_FREQ_MASK_BIT | WRITE_LEVELING_MASK_BIT |
-			  /* LOAD_PATTERN_2_MASK_BIT | */
-			  WRITE_LEVELING_SUPP_MASK_BIT |
-			  READ_LEVELING_MASK_BIT |
-			  PBS_RX_MASK_BIT |
-			  PBS_TX_MASK_BIT |
-			  SET_TARGET_FREQ_MASK_BIT |
-			  WRITE_LEVELING_TF_MASK_BIT |
-			  WRITE_LEVELING_SUPP_TF_MASK_BIT |
-			  READ_LEVELING_TF_MASK_BIT |
-			  CENTRALIZATION_RX_MASK_BIT |
-			  CENTRALIZATION_TX_MASK_BIT);
-	rl_mid_freq_wa = 1;
-
-	if ((ddr_freq == DDR_FREQ_333) || (ddr_freq == DDR_FREQ_400)) {
-		mask_tune_func = (WRITE_LEVELING_MASK_BIT |
-				  LOAD_PATTERN_2_MASK_BIT |
-				  WRITE_LEVELING_SUPP_MASK_BIT |
-				  READ_LEVELING_MASK_BIT |
-				  PBS_RX_MASK_BIT |
-				  PBS_TX_MASK_BIT |
-				  CENTRALIZATION_RX_MASK_BIT |
-				  CENTRALIZATION_TX_MASK_BIT);
-		rl_mid_freq_wa = 0; /* WA not needed if 333/400 is TF */
-	}
-
-	/* Supplementary not supported for ECC modes */
-	if (1 == ddr3_if_ecc_enabled()) {
-		mask_tune_func &= ~WRITE_LEVELING_SUPP_TF_MASK_BIT;
-		mask_tune_func &= ~WRITE_LEVELING_SUPP_MASK_BIT;
-		mask_tune_func &= ~PBS_TX_MASK_BIT;
-		mask_tune_func &= ~PBS_RX_MASK_BIT;
-	}
-
-	if (ck_delay == -1)
-		ck_delay = 160;
-	if (ck_delay_16 == -1)
-		ck_delay_16 = 160;
-	ca_delay = 0;
-	delay_enable = 1;
-
-	calibration_update_control = 1;
-
-	init_freq = tm->interface_params[first_active_if].memory_freq;
-
-	ddr3_tip_a38x_get_medium_freq(dev_num, &medium_freq);
-
-	return MV_OK;
-}
-
-int ddr3_a38x_update_topology_map(u32 dev_num, struct hws_topology_map *tm)
-{
-	u32 if_id = 0;
-	enum hws_ddr_freq freq;
-
-	ddr3_tip_a38x_get_init_freq(dev_num, &freq);
-	tm->interface_params[if_id].memory_freq = freq;
-
-	/*
-	 * re-calc topology parameters according to topology updates
-	 * (if needed)
-	 */
-	CHECK_STATUS(hws_ddr3_tip_load_topology_map(dev_num, tm));
-
-	return MV_OK;
-}
-
-int ddr3_tip_init_a38x(u32 dev_num, u32 board_id)
-{
-	struct hws_topology_map *tm = ddr3_get_topology_map();
-
-	if (NULL == tm)
-		return MV_FAIL;
-
-	ddr3_a38x_update_topology_map(dev_num, tm);
-	ddr3_tip_init_a38x_silicon(dev_num, board_id);
-
-	return MV_OK;
-}
-
-int ddr3_tip_a38x_get_init_freq(int dev_num, enum hws_ddr_freq *freq)
-{
-	u32 reg;
-
-	/* Read sample at reset setting */
-	reg = (reg_read(REG_DEVICE_SAR1_ADDR) >>
-	       RST2_CPU_DDR_CLOCK_SELECT_IN_OFFSET) &
-		RST2_CPU_DDR_CLOCK_SELECT_IN_MASK;
-	switch (reg) {
-	case 0x0:
-	case 0x1:
-		*freq = DDR_FREQ_333;
-		break;
-	case 0x2:
-	case 0x3:
-		*freq = DDR_FREQ_400;
-		break;
-	case 0x4:
-	case 0xd:
-		*freq = DDR_FREQ_533;
-		break;
-	case 0x6:
-		*freq = DDR_FREQ_600;
-		break;
-	case 0x8:
-	case 0x11:
-	case 0x14:
-		*freq = DDR_FREQ_667;
-		break;
-	case 0xc:
-	case 0x15:
-	case 0x1b:
-		*freq = DDR_FREQ_800;
-		break;
-	case 0x10:
-		*freq = DDR_FREQ_933;
-		break;
-	case 0x12:
-		*freq = DDR_FREQ_900;
-		break;
-	case 0x13:
-		*freq = DDR_FREQ_900;
-		break;
-	default:
-		*freq = 0;
-		return MV_NOT_SUPPORTED;
-	}
-
-	return MV_OK;
-}
-
-int ddr3_tip_a38x_get_medium_freq(int dev_num, enum hws_ddr_freq *freq)
-{
-	u32 reg;
-
-	/* Read sample at reset setting */
-	reg = (reg_read(REG_DEVICE_SAR1_ADDR) >>
-	       RST2_CPU_DDR_CLOCK_SELECT_IN_OFFSET) &
-		RST2_CPU_DDR_CLOCK_SELECT_IN_MASK;
-	switch (reg) {
-	case 0x0:
-	case 0x1:
-		/* Medium is same as TF to run PBS in this freq */
-		*freq = DDR_FREQ_333;
-		break;
-	case 0x2:
-	case 0x3:
-		/* Medium is same as TF to run PBS in this freq */
-		*freq = DDR_FREQ_400;
-		break;
-	case 0x4:
-	case 0xd:
-		*freq = DDR_FREQ_533;
-		break;
-	case 0x8:
-	case 0x11:
-	case 0x14:
-		*freq = DDR_FREQ_333;
-		break;
-	case 0xc:
-	case 0x15:
-	case 0x1b:
-		*freq = DDR_FREQ_400;
-		break;
-	case 0x6:
-		*freq = DDR_FREQ_300;
-		break;
-	case 0x12:
-		*freq = DDR_FREQ_360;
-		break;
-	case 0x13:
-		*freq = DDR_FREQ_400;
-		break;
-	default:
-		*freq = 0;
-		return MV_NOT_SUPPORTED;
-	}
-
-	return MV_OK;
-}
-
-u32 ddr3_tip_get_init_freq(void)
-{
-	enum hws_ddr_freq freq;
-
-	ddr3_tip_a38x_get_init_freq(0, &freq);
-
-	return freq;
-}
-
-static int ddr3_tip_a38x_set_divider(u8 dev_num, u32 if_id,
-				     enum hws_ddr_freq frequency)
-{
-	u32 divider = 0;
-	u32 sar_val;
-
-	if (if_id != 0) {
-		DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR,
-				      ("A38x does not support interface 0x%x\n",
-				       if_id));
-		return MV_BAD_PARAM;
-	}
-
-	/* get VCO freq index */
-	sar_val = (reg_read(REG_DEVICE_SAR1_ADDR) >>
-		   RST2_CPU_DDR_CLOCK_SELECT_IN_OFFSET) &
-		RST2_CPU_DDR_CLOCK_SELECT_IN_MASK;
-	divider = a38x_vco_freq_per_sar[sar_val] / freq_val[frequency];
-
-	/* Set Sync mode */
-	CHECK_STATUS(ddr3_tip_a38x_if_write
-		     (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x20220, 0x0,
-		      0x1000));
-	CHECK_STATUS(ddr3_tip_a38x_if_write
-		     (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe42f4, 0x0,
-		      0x200));
-
-	/* cpupll_clkdiv_reset_mask */
-	CHECK_STATUS(ddr3_tip_a38x_if_write
-		     (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4264, 0x1f,
-		      0xff));
-
-	/* cpupll_clkdiv_reload_smooth */
-	CHECK_STATUS(ddr3_tip_a38x_if_write
-		     (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4260,
-		      (0x2 << 8), (0xff << 8)));
-
-	/* cpupll_clkdiv_relax_en */
-	CHECK_STATUS(ddr3_tip_a38x_if_write
-		     (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4260,
-		      (0x2 << 24), (0xff << 24)));
-
-	/* write the divider */
-	CHECK_STATUS(ddr3_tip_a38x_if_write
-		     (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4268,
-		      (divider << 8), (0x3f << 8)));
-
-	/* set cpupll_clkdiv_reload_ratio */
-	CHECK_STATUS(ddr3_tip_a38x_if_write
-		     (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4264,
-		      (1 << 8), (1 << 8)));
-
-	/* undet cpupll_clkdiv_reload_ratio */
-	CHECK_STATUS(ddr3_tip_a38x_if_write
-		     (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4264, 0,
-		      (1 << 8)));
-
-	/* clear cpupll_clkdiv_reload_force */
-	CHECK_STATUS(ddr3_tip_a38x_if_write
-		     (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4260, 0,
-		      (0xff << 8)));
-
-	/* clear cpupll_clkdiv_relax_en */
-	CHECK_STATUS(ddr3_tip_a38x_if_write
-		     (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4260, 0,
-		      (0xff << 24)));
-
-	/* clear cpupll_clkdiv_reset_mask */
-	CHECK_STATUS(ddr3_tip_a38x_if_write
-		     (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4264, 0,
-		      0xff));
-
-	/* Dunit training clock + 1:1 mode */
-	if ((frequency == DDR_FREQ_LOW_FREQ) || (freq_val[frequency] <= 400)) {
-		CHECK_STATUS(ddr3_tip_a38x_if_write
-			     (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x18488,
-			      (1 << 16), (1 << 16)));
-		CHECK_STATUS(ddr3_tip_a38x_if_write
-			     (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x1524,
-			      (0 << 15), (1 << 15)));
-	} else {
-		CHECK_STATUS(ddr3_tip_a38x_if_write
-			     (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x18488,
-			      0, (1 << 16)));
-		CHECK_STATUS(ddr3_tip_a38x_if_write
-			     (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x1524,
-			      (1 << 15), (1 << 15)));
-	}
-
-	return MV_OK;
-}
-
-/*
- * external read from memory
- */
-int ddr3_tip_ext_read(u32 dev_num, u32 if_id, u32 reg_addr,
-		      u32 num_of_bursts, u32 *data)
-{
-	u32 burst_num;
-
-	for (burst_num = 0; burst_num < num_of_bursts * 8; burst_num++)
-		data[burst_num] = readl(reg_addr + 4 * burst_num);
-
-	return MV_OK;
-}
-
-/*
- * external write to memory
- */
-int ddr3_tip_ext_write(u32 dev_num, u32 if_id, u32 reg_addr,
-		       u32 num_of_bursts, u32 *data) {
-	u32 burst_num;
-
-	for (burst_num = 0; burst_num < num_of_bursts * 8; burst_num++)
-		writel(data[burst_num], reg_addr + 4 * burst_num);
-
-	return MV_OK;
-}
-
-int ddr3_silicon_pre_init(void)
-{
-	return ddr3_silicon_init();
-}
-
-int ddr3_post_run_alg(void)
-{
-	return MV_OK;
-}
-
-int ddr3_silicon_post_init(void)
-{
-	struct hws_topology_map *tm = ddr3_get_topology_map();
-
-	/* Set half bus width */
-	if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask)) {
-		CHECK_STATUS(ddr3_tip_if_write
-			     (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE,
-			      REG_SDRAM_CONFIG_ADDR, 0x0, 0x8000));
-	}
-
-	return MV_OK;
-}
-
-int ddr3_tip_a38x_get_device_info(u8 dev_num, struct ddr3_device_info *info_ptr)
-{
-	info_ptr->device_id = 0x6800;
-	info_ptr->ck_delay = ck_delay;
-
-	return MV_OK;
-}
diff --git a/drivers/ddr/marvell/a38x/ddr3_a38x.h b/drivers/ddr/marvell/a38x/ddr3_a38x.h
deleted file mode 100644
index 1ed517446f95..000000000000
--- a/drivers/ddr/marvell/a38x/ddr3_a38x.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- *
- * SPDX-License-Identifier:	GPL-2.0
- */
-
-#ifndef _DDR3_A38X_H
-#define _DDR3_A38X_H
-
-#define MAX_INTERFACE_NUM		1
-#define MAX_BUS_NUM			5
-
-#include "ddr3_hws_hw_training_def.h"
-
-#define ECC_SUPPORT
-
-/* right now, we're not supporting this in mainline */
-#undef SUPPORT_STATIC_DUNIT_CONFIG
-
-/* Controler bus divider 1 for 32 bit, 2 for 64 bit */
-#define DDR_CONTROLLER_BUS_WIDTH_MULTIPLIER	1
-
-/* Tune internal training params values */
-#define TUNE_TRAINING_PARAMS_CK_DELAY		160
-#define TUNE_TRAINING_PARAMS_CK_DELAY_16	160
-#define TUNE_TRAINING_PARAMS_PFINGER		41
-#define TUNE_TRAINING_PARAMS_NFINGER		43
-#define TUNE_TRAINING_PARAMS_PHYREG3VAL		0xa
-
-#define MARVELL_BOARD				MARVELL_BOARD_ID_BASE
-
-
-#define REG_DEVICE_SAR1_ADDR			0xe4204
-#define RST2_CPU_DDR_CLOCK_SELECT_IN_OFFSET	17
-#define RST2_CPU_DDR_CLOCK_SELECT_IN_MASK	0x1f
-
-/* DRAM Windows */
-#define REG_XBAR_WIN_5_CTRL_ADDR		0x20050
-#define REG_XBAR_WIN_5_BASE_ADDR		0x20054
-
-/* DRAM Windows */
-#define REG_XBAR_WIN_4_CTRL_ADDR                0x20040
-#define REG_XBAR_WIN_4_BASE_ADDR                0x20044
-#define REG_XBAR_WIN_4_REMAP_ADDR               0x20048
-#define REG_XBAR_WIN_7_REMAP_ADDR               0x20078
-#define REG_XBAR_WIN_16_CTRL_ADDR               0x200d0
-#define REG_XBAR_WIN_16_BASE_ADDR               0x200d4
-#define REG_XBAR_WIN_16_REMAP_ADDR              0x200dc
-#define REG_XBAR_WIN_19_CTRL_ADDR               0x200e8
-
-#define REG_FASTPATH_WIN_BASE_ADDR(win)         (0x20180 + (0x8 * win))
-#define REG_FASTPATH_WIN_CTRL_ADDR(win)         (0x20184 + (0x8 * win))
-
-/* SatR defined too change topology busWidth and ECC configuration */
-#define DDR_SATR_CONFIG_MASK_WIDTH		0x8
-#define DDR_SATR_CONFIG_MASK_ECC		0x10
-#define DDR_SATR_CONFIG_MASK_ECC_PUP		0x20
-
-#define	REG_SAMPLE_RESET_HIGH_ADDR		0x18600
-
-#define MV_BOARD_REFCLK				MV_BOARD_REFCLK_25MHZ
-
-/* Matrix enables DRAM modes (bus width/ECC) per boardId */
-#define TOPOLOGY_UPDATE_32BIT			0
-#define TOPOLOGY_UPDATE_32BIT_ECC		1
-#define TOPOLOGY_UPDATE_16BIT			2
-#define TOPOLOGY_UPDATE_16BIT_ECC		3
-#define TOPOLOGY_UPDATE_16BIT_ECC_PUP3		4
-#define TOPOLOGY_UPDATE { \
-		/* 32Bit, 32bit ECC, 16bit, 16bit ECC PUP4, 16bit ECC PUP3 */ \
-		{1, 1, 1, 1, 1},	/* RD_NAS_68XX_ID */ \
-		{1, 1, 1, 1, 1},	/* DB_68XX_ID	  */ \
-		{1, 0, 1, 0, 1},	/* RD_AP_68XX_ID  */ \
-		{1, 0, 1, 0, 1},	/* DB_AP_68XX_ID  */ \
-		{1, 0, 1, 0, 1},	/* DB_GP_68XX_ID  */ \
-		{0, 0, 1, 1, 0},	/* DB_BP_6821_ID  */ \
-		{1, 1, 1, 1, 1}		/* DB_AMC_6820_ID */ \
-	};
-
-enum {
-	CPU_1066MHZ_DDR_400MHZ,
-	CPU_RESERVED_DDR_RESERVED0,
-	CPU_667MHZ_DDR_667MHZ,
-	CPU_800MHZ_DDR_800MHZ,
-	CPU_RESERVED_DDR_RESERVED1,
-	CPU_RESERVED_DDR_RESERVED2,
-	CPU_RESERVED_DDR_RESERVED3,
-	LAST_FREQ
-};
-
-#define ACTIVE_INTERFACE_MASK			0x1
-
-#endif /* _DDR3_A38X_H */
diff --git a/drivers/ddr/marvell/a38x/ddr3_a38x_topology.h b/drivers/ddr/marvell/a38x/ddr3_a38x_topology.h
deleted file mode 100644
index f27bbff73383..000000000000
--- a/drivers/ddr/marvell/a38x/ddr3_a38x_topology.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- *
- * SPDX-License-Identifier:	GPL-2.0
- */
-
-#ifndef _DDR3_A38X_TOPOLOGY_H
-#define _DDR3_A38X_TOPOLOGY_H
-
-#include "ddr_topology_def.h"
-
-/* Bus mask variants */
-#define BUS_MASK_32BIT			0xf
-#define BUS_MASK_32BIT_ECC		0x1f
-#define BUS_MASK_16BIT			0x3
-#define BUS_MASK_16BIT_ECC		0x13
-#define BUS_MASK_16BIT_ECC_PUP3		0xb
-
-#define DYNAMIC_CS_SIZE_CONFIG
-#define DISABLE_L2_FILTERING_DURING_DDR_TRAINING
-
-#endif /* _DDR3_A38X_TOPOLOGY_H */
diff --git a/drivers/ddr/marvell/a38x/ddr3_a38x_training.c b/drivers/ddr/marvell/a38x/ddr3_a38x_training.c
deleted file mode 100644
index 52c43f75e080..000000000000
--- a/drivers/ddr/marvell/a38x/ddr3_a38x_training.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- *
- * SPDX-License-Identifier:	GPL-2.0
- */
-
-#include <common.h>
-#include <i2c.h>
-#include <spl.h>
-#include <asm/io.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/soc.h>
-
-#include "ddr3_init.h"
-
-/*
- * Name:     ddr3_tip_init_silicon
- * Desc:     initiate silicon parameters
- * Args:
- * Notes:
- * Returns:  required value
- */
-int ddr3_silicon_init(void)
-{
-	int status;
-	static int init_done;
-
-	if (init_done == 1)
-		return MV_OK;
-
-	status = ddr3_tip_init_a38x(0, 0);
-	if (MV_OK != status) {
-		printf("DDR3 A38x silicon init - FAILED 0x%x\n", status);
-		return status;
-	}
-
-	init_done = 1;
-
-	return MV_OK;
-}
diff --git a/drivers/ddr/marvell/a38x/ddr3_debug.c b/drivers/ddr/marvell/a38x/ddr3_debug.c
index f0c8daa4b62c..589636f13372 100644
--- a/drivers/ddr/marvell/a38x/ddr3_debug.c
+++ b/drivers/ddr/marvell/a38x/ddr3_debug.c
@@ -4,13 +4,6 @@
  * SPDX-License-Identifier:	GPL-2.0
  */
 
-#include <common.h>
-#include <i2c.h>
-#include <spl.h>
-#include <asm/io.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/soc.h>
-
 #include "ddr3_init.h"
 
 u8 is_reg_dump = 0;
@@ -19,7 +12,12 @@ u8 debug_pbs = DEBUG_LEVEL_ERROR;
 /*
  * API to change flags outside of the lib
  */
-#ifndef SILENT_LIB
+#if defined(SILENT_LIB)
+void ddr3_hws_set_log_level(enum ddr_lib_debug_block block, u8 level)
+{
+	/* do nothing */
+}
+#else /* SILENT_LIB */
 /* Debug flags for other Training modules */
 u8 debug_training_static = DEBUG_LEVEL_ERROR;
 u8 debug_training = DEBUG_LEVEL_ERROR;
@@ -29,7 +27,14 @@ u8 debug_training_ip = DEBUG_LEVEL_ERROR;
 u8 debug_training_bist = DEBUG_LEVEL_ERROR;
 u8 debug_training_hw_alg = DEBUG_LEVEL_ERROR;
 u8 debug_training_access = DEBUG_LEVEL_ERROR;
-u8 debug_training_a38x = DEBUG_LEVEL_ERROR;
+u8 debug_training_device = DEBUG_LEVEL_ERROR;
+
+
+void mv_ddr_user_log_level_set(enum ddr_lib_debug_block block)
+{
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+	ddr3_hws_set_log_level(block, tm->debug_level);
+};
 
 void ddr3_hws_set_log_level(enum ddr_lib_debug_block block, u8 level)
 {
@@ -53,7 +58,7 @@ void ddr3_hws_set_log_level(enum ddr_lib_debug_block block, u8 level)
 		debug_training_hw_alg = level;
 		break;
 	case DEBUG_BLOCK_DEVICE:
-		debug_training_a38x = level;
+		debug_training_device = level;
 		break;
 	case DEBUG_BLOCK_ACCESS:
 		debug_training_access = level;
@@ -73,24 +78,31 @@ void ddr3_hws_set_log_level(enum ddr_lib_debug_block block, u8 level)
 		debug_pbs = level;
 		debug_training_hw_alg = level;
 		debug_training_access = level;
-		debug_training_a38x = level;
+		debug_training_device = level;
 	}
 }
-#else
-void ddr3_hws_set_log_level(enum ddr_lib_debug_block block, u8 level)
-{
-	return;
-}
-#endif
+#endif /* SILENT_LIB */
 
-struct hws_tip_config_func_db config_func_info[HWS_MAX_DEVICE_NUM];
+#if defined(DDR_VIEWER_TOOL)
+static char *convert_freq(enum hws_ddr_freq freq);
+#if defined(EXCLUDE_SWITCH_DEBUG)
+u32 ctrl_sweepres[ADLL_LENGTH][MAX_INTERFACE_NUM][MAX_BUS_NUM];
+u32 ctrl_adll[MAX_CS_NUM * MAX_INTERFACE_NUM * MAX_BUS_NUM];
+u32 ctrl_adll1[MAX_CS_NUM * MAX_INTERFACE_NUM * MAX_BUS_NUM];
+u32 ctrl_level_phase[MAX_CS_NUM * MAX_INTERFACE_NUM * MAX_BUS_NUM];
+#endif /* EXCLUDE_SWITCH_DEBUG */
+#endif /* DDR_VIEWER_TOOL */
+
+struct hws_tip_config_func_db config_func_info[MAX_DEVICE_NUM];
 u8 is_default_centralization = 0;
 u8 is_tune_result = 0;
 u8 is_validate_window_per_if = 0;
 u8 is_validate_window_per_pup = 0;
 u8 sweep_cnt = 1;
 u32 is_bist_reset_bit = 1;
-static struct hws_xsb_info xsb_info[HWS_MAX_DEVICE_NUM];
+u8 is_run_leveling_sweep_tests;
+
+static struct hws_xsb_info xsb_info[MAX_DEVICE_NUM];
 
 /*
  * Dump Dunit & Phy registers
@@ -99,13 +111,14 @@ int ddr3_tip_reg_dump(u32 dev_num)
 {
 	u32 if_id, reg_addr, data_value, bus_id;
 	u32 read_data[MAX_INTERFACE_NUM];
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	printf("-- dunit registers --\n");
 	for (reg_addr = 0x1400; reg_addr < 0x19f0; reg_addr += 4) {
 		printf("0x%x ", reg_addr);
 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 			CHECK_STATUS(ddr3_tip_if_read
 				     (dev_num, ACCESS_TYPE_UNICAST,
 				      if_id, reg_addr, read_data,
@@ -119,11 +132,11 @@ int ddr3_tip_reg_dump(u32 dev_num)
 	for (reg_addr = 0; reg_addr <= 0xff; reg_addr++) {
 		printf("0x%x ", reg_addr);
 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 			for (bus_id = 0;
-			     bus_id < tm->num_of_bus_per_interface;
+			     bus_id < octets_per_if_num;
 			     bus_id++) {
-				VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+				VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
 				CHECK_STATUS(ddr3_tip_bus_read
 					     (dev_num, if_id,
 					      ACCESS_TYPE_UNICAST, bus_id,
@@ -132,9 +145,9 @@ int ddr3_tip_reg_dump(u32 dev_num)
 				printf("0x%x ", data_value);
 			}
 			for (bus_id = 0;
-			     bus_id < tm->num_of_bus_per_interface;
+			     bus_id < octets_per_if_num;
 			     bus_id++) {
-				VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+				VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
 				CHECK_STATUS(ddr3_tip_bus_read
 					     (dev_num, if_id,
 					      ACCESS_TYPE_UNICAST, bus_id,
@@ -164,6 +177,23 @@ int ddr3_tip_init_config_func(u32 dev_num,
 	return MV_OK;
 }
 
+/*
+ * Read training result table
+ */
+int hws_ddr3_tip_read_training_result(
+	u32 dev_num, enum hws_result result[MAX_STAGE_LIMIT][MAX_INTERFACE_NUM])
+{
+	if (result == NULL)
+		return MV_BAD_PARAM;
+
+	memcpy(result, training_result,
+	       sizeof(enum hws_result) *
+	       MAX_STAGE_LIMIT *
+	       MAX_INTERFACE_NUM);
+
+	return MV_OK;
+}
+
 /*
  * Get training result info pointer
  */
@@ -185,7 +215,7 @@ int ddr3_tip_get_device_info(u32 dev_num, struct ddr3_device_info *info_ptr)
 	return MV_FAIL;
 }
 
-#ifndef EXCLUDE_SWITCH_DEBUG
+#if defined(DDR_VIEWER_TOOL)
 /*
  * Convert freq to character string
  */
@@ -194,11 +224,13 @@ static char *convert_freq(enum hws_ddr_freq freq)
 	switch (freq) {
 	case DDR_FREQ_LOW_FREQ:
 		return "DDR_FREQ_LOW_FREQ";
+
 	case DDR_FREQ_400:
 		return "400";
 
 	case DDR_FREQ_533:
 		return "533";
+
 	case DDR_FREQ_667:
 		return "667";
 
@@ -210,6 +242,7 @@ static char *convert_freq(enum hws_ddr_freq freq)
 
 	case DDR_FREQ_1066:
 		return "1066";
+
 	case DDR_FREQ_311:
 		return "311";
 
@@ -230,6 +263,7 @@ static char *convert_freq(enum hws_ddr_freq freq)
 
 	case DDR_FREQ_1000:
 		return "DDR_FREQ_1000";
+
 	default:
 		return "Unknown Frequency";
 	}
@@ -280,7 +314,7 @@ static char *convert_mem_size(u32 dev_id)
 int print_device_info(u8 dev_num)
 {
 	struct ddr3_device_info info_ptr;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	CHECK_STATUS(ddr3_tip_get_device_info(dev_num, &info_ptr));
 	printf("=== DDR setup START===\n");
@@ -303,7 +337,7 @@ void hws_ddr3_tip_sweep_test(int enable)
 		is_validate_window_per_pup = 0;
 	}
 }
-#endif
+#endif /* DDR_VIEWER_TOOL */
 
 char *ddr3_tip_convert_tune_result(enum hws_result tune_result)
 {
@@ -325,9 +359,9 @@ char *ddr3_tip_convert_tune_result(enum hws_result tune_result)
 int ddr3_tip_print_log(u32 dev_num, u32 mem_addr)
 {
 	u32 if_id = 0;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
-#ifndef EXCLUDE_SWITCH_DEBUG
+#if defined(DDR_VIEWER_TOOL)
 	if ((is_validate_window_per_if != 0) ||
 	    (is_validate_window_per_pup != 0)) {
 		u32 is_pup_log = 0;
@@ -341,16 +375,22 @@ int ddr3_tip_print_log(u32 dev_num, u32 mem_addr)
 		/* print sweep windows */
 		ddr3_tip_run_sweep_test(dev_num, sweep_cnt, 1, is_pup_log);
 		ddr3_tip_run_sweep_test(dev_num, sweep_cnt, 0, is_pup_log);
+#if defined(EXCLUDE_SWITCH_DEBUG)
+		if (is_run_leveling_sweep_tests == 1) {
+			ddr3_tip_run_leveling_sweep_test(dev_num, sweep_cnt, 0, is_pup_log);
+			ddr3_tip_run_leveling_sweep_test(dev_num, sweep_cnt, 1, is_pup_log);
+		}
+#endif /* EXCLUDE_SWITCH_DEBUG */
 		ddr3_tip_print_all_pbs_result(dev_num);
 		ddr3_tip_print_wl_supp_result(dev_num);
 		printf("===VALIDATE WINDOW LOG END ===\n");
 		CHECK_STATUS(ddr3_tip_restore_dunit_regs(dev_num));
 		ddr3_tip_reg_dump(dev_num);
 	}
-#endif
+#endif /* DDR_VIEWER_TOOL */
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 
 		DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
 				  ("IF %d Status:\n", if_id));
@@ -480,6 +520,7 @@ int ddr3_tip_print_log(u32 dev_num, u32 mem_addr)
 	return MV_OK;
 }
 
+#if !defined(EXCLUDE_DEBUG_PRINTS)
 /*
  * Print stability log info
  */
@@ -488,17 +529,17 @@ int ddr3_tip_print_stability_log(u32 dev_num)
 	u8 if_id = 0, csindex = 0, bus_id = 0, idx = 0;
 	u32 reg_data;
 	u32 read_data[MAX_INTERFACE_NUM];
-	u32 max_cs = hws_ddr3_tip_max_cs_get();
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 max_cs = ddr3_tip_max_cs_get(dev_num);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	/* Title print */
 	for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		printf("Title: I/F# , Tj, Calibration_n0, Calibration_p0, Calibration_n1, Calibration_p1, Calibration_n2, Calibration_p2,");
 		for (csindex = 0; csindex < max_cs; csindex++) {
 			printf("CS%d , ", csindex);
 			printf("\n");
-			VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
 			printf("VWTx, VWRx, WL_tot, WL_ADLL, WL_PH, RL_Tot, RL_ADLL, RL_PH, RL_Smp, Cen_tx, Cen_rx, Vref, DQVref,");
 			printf("\t\t");
 			for (idx = 0; idx < 11; idx++)
@@ -512,7 +553,7 @@ int ddr3_tip_print_stability_log(u32 dev_num)
 
 	/* Data print */
 	for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 
 		printf("Data: %d,%d,", if_id,
 		       (config_func_info[dev_num].tip_get_temperature != NULL)
@@ -539,11 +580,11 @@ int ddr3_tip_print_stability_log(u32 dev_num)
 			printf("CS%d , ", csindex);
 			for (bus_id = 0; bus_id < MAX_BUS_NUM; bus_id++) {
 				printf("\n");
-				VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+				VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
 				ddr3_tip_bus_read(dev_num, if_id,
 						  ACCESS_TYPE_UNICAST,
 						  bus_id, DDR_PHY_DATA,
-						  RESULT_DB_PHY_REG_ADDR +
+						  RESULT_PHY_REG +
 						  csindex, &reg_data);
 				printf("%d,%d,", (reg_data & 0x1f),
 				       ((reg_data & 0x3e0) >> 5));
@@ -551,8 +592,8 @@ int ddr3_tip_print_stability_log(u32 dev_num)
 				ddr3_tip_bus_read(dev_num, if_id,
 						  ACCESS_TYPE_UNICAST,
 						  bus_id, DDR_PHY_DATA,
-						  WL_PHY_REG +
-						  csindex * 4, &reg_data);
+						  WL_PHY_REG(csindex),
+						  &reg_data);
 				printf("%d,%d,%d,",
 				       (reg_data & 0x1f) +
 				       ((reg_data & 0x1c0) >> 6) * 32,
@@ -562,16 +603,16 @@ int ddr3_tip_print_stability_log(u32 dev_num)
 				CHECK_STATUS(ddr3_tip_if_read
 					     (dev_num, ACCESS_TYPE_UNICAST,
 					      if_id,
-					      READ_DATA_SAMPLE_DELAY,
+					      RD_DATA_SMPL_DLYS_REG,
 					      read_data, MASK_ALL_BITS));
 				read_data[if_id] =
 					(read_data[if_id] &
-					 (0xf << (4 * csindex))) >>
-					(4 * csindex);
+					 (0x1f << (8 * csindex))) >>
+					(8 * csindex);
 				ddr3_tip_bus_read(dev_num, if_id,
 						  ACCESS_TYPE_UNICAST, bus_id,
 						  DDR_PHY_DATA,
-						  RL_PHY_REG + csindex * 4,
+						  RL_PHY_REG(csindex),
 						  &reg_data);
 				printf("%d,%d,%d,%d,",
 				       (reg_data & 0x1f) +
@@ -584,36 +625,26 @@ int ddr3_tip_print_stability_log(u32 dev_num)
 				ddr3_tip_bus_read(dev_num, if_id,
 						  ACCESS_TYPE_UNICAST, bus_id,
 						  DDR_PHY_DATA,
-						  WRITE_CENTRALIZATION_PHY_REG
-						  + csindex * 4, &reg_data);
+						  CTX_PHY_REG(csindex),
+						  &reg_data);
 				printf("%d,", (reg_data & 0x3f));
 				ddr3_tip_bus_read(dev_num, if_id,
 						  ACCESS_TYPE_UNICAST, bus_id,
 						  DDR_PHY_DATA,
-						  READ_CENTRALIZATION_PHY_REG
-						  + csindex * 4, &reg_data);
+						  CRX_PHY_REG(csindex),
+						   &reg_data);
 				printf("%d,", (reg_data & 0x1f));
 				/* Vref */
 				ddr3_tip_bus_read(dev_num, if_id,
 						  ACCESS_TYPE_UNICAST, bus_id,
 						  DDR_PHY_DATA,
-						  PAD_CONFIG_PHY_REG,
+						  PAD_CFG_PHY_REG,
 						  &reg_data);
 				printf("%d,", (reg_data & 0x7));
 				/* DQVref */
 				/* Need to add the Read Function from device */
 				printf("%d,", 0);
 				printf("\t\t");
-				for (idx = 0; idx < 11; idx++) {
-					ddr3_tip_bus_read(dev_num, if_id,
-							  ACCESS_TYPE_UNICAST,
-							  bus_id, DDR_PHY_DATA,
-							  0xd0 +
-							  12 * csindex +
-							  idx, &reg_data);
-					printf("%d,", (reg_data & 0x3f));
-				}
-				printf("\t\t");
 				for (idx = 0; idx < 11; idx++) {
 					ddr3_tip_bus_read(dev_num, if_id,
 							  ACCESS_TYPE_UNICAST,
@@ -640,6 +671,7 @@ int ddr3_tip_print_stability_log(u32 dev_num)
 
 	return MV_OK;
 }
+#endif /* EXCLUDE_DEBUG_PRINTS */
 
 /*
  * Register XSB information
@@ -653,30 +685,30 @@ int ddr3_tip_register_xsb_info(u32 dev_num, struct hws_xsb_info *xsb_info_table)
 /*
  * Read ADLL Value
  */
-int read_adll_value(u32 pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
-		    int reg_addr, u32 mask)
+int ddr3_tip_read_adll_value(u32 dev_num, u32 pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
+			     u32 reg_addr, u32 mask)
 {
 	u32 data_value;
 	u32 if_id = 0, bus_id = 0;
-	u32 dev_num = 0;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	/*
 	 * multi CS support - reg_addr is calucalated in calling function
 	 * with CS offset
 	 */
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-		for (bus_id = 0; bus_id < tm->num_of_bus_per_interface;
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+		for (bus_id = 0; bus_id < octets_per_if_num;
 		     bus_id++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
 			CHECK_STATUS(ddr3_tip_bus_read(dev_num, if_id,
 						       ACCESS_TYPE_UNICAST,
 						       bus_id,
 						       DDR_PHY_DATA, reg_addr,
 						       &data_value));
 			pup_values[if_id *
-				   tm->num_of_bus_per_interface + bus_id] =
+				   octets_per_if_num + bus_id] =
 				data_value & mask;
 		}
 	}
@@ -687,24 +719,25 @@ int read_adll_value(u32 pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
 /*
  * Write ADLL Value
  */
-int write_adll_value(u32 pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
-		     int reg_addr)
+int ddr3_tip_write_adll_value(u32 dev_num, u32 pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
+			      u32 reg_addr)
 {
 	u32 if_id = 0, bus_id = 0;
-	u32 dev_num = 0, data;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 data;
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	/*
 	 * multi CS support - reg_addr is calucalated in calling function
 	 * with CS offset
 	 */
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-		for (bus_id = 0; bus_id < tm->num_of_bus_per_interface;
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+		for (bus_id = 0; bus_id < octets_per_if_num;
 		     bus_id++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
 			data = pup_values[if_id *
-					  tm->num_of_bus_per_interface +
+					  octets_per_if_num +
 					  bus_id];
 			CHECK_STATUS(ddr3_tip_bus_write(dev_num,
 							ACCESS_TYPE_UNICAST,
@@ -718,23 +751,78 @@ int write_adll_value(u32 pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
 	return 0;
 }
 
-#ifndef EXCLUDE_SWITCH_DEBUG
-u32 rl_version = 1;		/* 0 - old RL machine */
-struct hws_tip_config_func_db config_func_info[HWS_MAX_DEVICE_NUM];
+/**
+ * Read Phase Value
+ */
+int read_phase_value(u32 dev_num, u32 pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
+		     int reg_addr, u32 mask)
+{
+	u32  data_value;
+	u32 if_id = 0, bus_id = 0;
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+
+	/* multi CS support - reg_addr is calucalated in calling function with CS offset */
+	for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+		for (bus_id = 0; bus_id < octets_per_if_num; bus_id++) {
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
+			CHECK_STATUS(ddr3_tip_bus_read(dev_num, if_id,
+						       ACCESS_TYPE_UNICAST,
+						       bus_id,
+						       DDR_PHY_DATA, reg_addr,
+						       &data_value));
+			pup_values[if_id * octets_per_if_num + bus_id] = data_value & mask;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * Write Leveling Value
+ */
+int write_leveling_value(u32 dev_num, u32 pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
+			 u32 pup_ph_values[MAX_INTERFACE_NUM * MAX_BUS_NUM], int reg_addr)
+{
+	u32 if_id = 0, bus_id = 0;
+	u32 data;
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+
+	/* multi CS support - reg_addr is calucalated in calling function with CS offset */
+	for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+		for (bus_id = 0 ; bus_id < octets_per_if_num ; bus_id++) {
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
+			data = pup_values[if_id * octets_per_if_num + bus_id] +
+			       pup_ph_values[if_id * octets_per_if_num + bus_id];
+			CHECK_STATUS(ddr3_tip_bus_write(dev_num,
+							ACCESS_TYPE_UNICAST,
+							if_id,
+							ACCESS_TYPE_UNICAST,
+							bus_id,
+							DDR_PHY_DATA,
+							reg_addr,
+							data));
+		}
+	}
+
+	return 0;
+}
+
+#if !defined(EXCLUDE_SWITCH_DEBUG)
+struct hws_tip_config_func_db config_func_info[MAX_DEVICE_NUM];
 u32 start_xsb_offset = 0;
 u8 is_rl_old = 0;
 u8 is_freq_old = 0;
 u8 is_dfs_disabled = 0;
 u32 default_centrlization_value = 0x12;
-u32 vref = 0x4;
 u32 activate_select_before_run_alg = 1, activate_deselect_after_run_alg = 1,
 	rl_test = 0, reset_read_fifo = 0;
 int debug_acc = 0;
 u32 ctrl_sweepres[ADLL_LENGTH][MAX_INTERFACE_NUM][MAX_BUS_NUM];
 u32 ctrl_adll[MAX_CS_NUM * MAX_INTERFACE_NUM * MAX_BUS_NUM];
-u8 cs_mask_reg[] = {
-	0, 4, 8, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
 
 u32 xsb_test_table[][8] = {
 	{0x00000000, 0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555,
@@ -762,13 +850,14 @@ static int ddr3_tip_access_atr(u32 dev_num, u32 flag_id, u32 value, u32 **ptr);
 int ddr3_tip_print_adll(void)
 {
 	u32 bus_cnt = 0, if_id, data_p1, data_p2, ui_data3, dev_num = 0;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-		for (bus_cnt = 0; bus_cnt < GET_TOPOLOGY_NUM_OF_BUSES();
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+		for (bus_cnt = 0; bus_cnt < octets_per_if_num;
 		     bus_cnt++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_cnt);
 			CHECK_STATUS(ddr3_tip_bus_read
 				     (dev_num, if_id,
 				      ACCESS_TYPE_UNICAST, bus_cnt,
@@ -816,7 +905,7 @@ int ddr3_tip_set_atr(u32 dev_num, u32 flag_id, u32 value)
 static int ddr3_tip_access_atr(u32 dev_num, u32 flag_id, u32 value, u32 **ptr)
 {
 	u32 tmp_val = 0, if_id = 0, pup_id = 0;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	*ptr = NULL;
 
@@ -830,21 +919,17 @@ static int ddr3_tip_access_atr(u32 dev_num, u32 flag_id, u32 value, u32 **ptr)
 		break;
 
 	case 0x2:
-		*ptr = (u32 *)&low_freq;
+		low_freq = (enum hws_ddr_freq)value;
 		break;
 
 	case 0x3:
-		*ptr = (u32 *)&medium_freq;
+		medium_freq = (enum hws_ddr_freq)value;
 		break;
 
 	case 0x4:
 		*ptr = (u32 *)&generic_init_controller;
 		break;
 
-	case 0x5:
-		*ptr = (u32 *)&rl_version;
-		break;
-
 	case 0x8:
 		*ptr = (u32 *)&start_xsb_offset;
 		break;
@@ -893,15 +978,14 @@ static int ddr3_tip_access_atr(u32 dev_num, u32 flag_id, u32 value, u32 **ptr)
 		break;
 
 	case 0x33:
-		*ptr = (u32 *)&p_finger;
+		*ptr = (u32 *)&g_zpodt_data;
 		break;
 
 	case 0x34:
-		*ptr = (u32 *)&n_finger;
+		*ptr = (u32 *)&g_znodt_data;
 		break;
 
 	case 0x35:
-		*ptr = (u32 *)&init_freq;
 		break;
 
 	case 0x36:
@@ -933,19 +1017,15 @@ static int ddr3_tip_access_atr(u32 dev_num, u32 flag_id, u32 value, u32 **ptr)
 		break;
 
 	case 0x4e:
-		*ptr = (u32 *)&sweep_pattern;
-		break;
-
-	case 0x50:
-		*ptr = (u32 *)&is_rzq6;
+		sweep_pattern = (enum hws_pattern)value;
 		break;
 
 	case 0x51:
-		*ptr = (u32 *)&znri_data_phy_val;
+		*ptr = (u32 *)&g_znri_data;
 		break;
 
 	case 0x52:
-		*ptr = (u32 *)&zpri_data_phy_val;
+		*ptr = (u32 *)&g_zpri_data;
 		break;
 
 	case 0x53:
@@ -977,11 +1057,11 @@ static int ddr3_tip_access_atr(u32 dev_num, u32 flag_id, u32 value, u32 **ptr)
 		break;
 
 	case 0x5a:
-		*ptr = (u32 *)&znri_ctrl_phy_val;
+		*ptr = (u32 *)&g_znri_ctrl;
 		break;
 
 	case 0x5b:
-		*ptr = (u32 *)&zpri_ctrl_phy_val;
+		*ptr = (u32 *)&g_zpri_ctrl;
 		break;
 
 	case 0x5c:
@@ -989,11 +1069,11 @@ static int ddr3_tip_access_atr(u32 dev_num, u32 flag_id, u32 value, u32 **ptr)
 		break;
 
 	case 0x5d:
-		*ptr = (u32 *)&vref;
+		*ptr = (u32 *)&vref_init_val;
 		break;
 
 	case 0x5e:
-		*ptr = (u32 *)&mode2_t;
+		*ptr = (u32 *)&mode_2t;
 		break;
 
 	case 0x5f:
@@ -1021,7 +1101,7 @@ static int ddr3_tip_access_atr(u32 dev_num, u32 flag_id, u32 value, u32 **ptr)
 		break;
 
 	case 0x71:
-		*ptr = (u32 *)&pbs_pattern;
+		pbs_pattern = (enum hws_pattern)value;
 		break;
 
 	case 0x72:
@@ -1032,10 +1112,6 @@ static int ddr3_tip_access_atr(u32 dev_num, u32 flag_id, u32 value, u32 **ptr)
 		*ptr = (u32 *)&ck_delay;
 		break;
 
-	case 0x74:
-		*ptr = (u32 *)&ck_delay_16;
-		break;
-
 	case 0x75:
 		*ptr = (u32 *)&ca_delay;
 		break;
@@ -1080,6 +1156,7 @@ static int ddr3_tip_access_atr(u32 dev_num, u32 flag_id, u32 value, u32 **ptr)
 		debug_training_access = (u8)value;
 		break;
 
+
 	case 0x112:
 		*ptr = &start_pattern;
 		break;
@@ -1148,28 +1225,46 @@ static int ddr3_tip_access_atr(u32 dev_num, u32 flag_id, u32 value, u32 **ptr)
 	return MV_OK;
 }
 
-#ifndef EXCLUDE_SWITCH_DEBUG
+#endif /* EXCLUDE_SWITCH_DEBUG */
+
+#if defined(DDR_VIEWER_TOOL)
 /*
  * Print ADLL
  */
 int print_adll(u32 dev_num, u32 adll[MAX_INTERFACE_NUM * MAX_BUS_NUM])
 {
 	u32 i, j;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
-	for (j = 0; j < tm->num_of_bus_per_interface; j++) {
-		VALIDATE_ACTIVE(tm->bus_act_mask, j);
-		for (i = 0; i < MAX_INTERFACE_NUM; i++) {
-			printf("%d ,",
-			       adll[i * tm->num_of_bus_per_interface + j]);
-		}
+	for (j = 0; j < octets_per_if_num; j++) {
+		VALIDATE_BUS_ACTIVE(tm->bus_act_mask, j);
+		for (i = 0; i < MAX_INTERFACE_NUM; i++)
+			printf("%d ,", adll[i * octets_per_if_num + j]);
 	}
 	printf("\n");
 
 	return MV_OK;
 }
-#endif
 
+int print_ph(u32 dev_num, u32 adll[MAX_INTERFACE_NUM * MAX_BUS_NUM])
+{
+	u32 i, j;
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+
+	for (j = 0; j < octets_per_if_num; j++) {
+		VALIDATE_BUS_ACTIVE(tm->bus_act_mask, j);
+		for (i = 0; i < MAX_INTERFACE_NUM; i++)
+			printf("%d ,", adll[i * octets_per_if_num + j] >> 6);
+	}
+	printf("\n");
+
+	return MV_OK;
+}
+#endif /* DDR_VIEWER_TOOL */
+
+#if !defined(EXCLUDE_SWITCH_DEBUG)
 /* byte_index - only byte 0, 1, 2, or 3, oxff - test all bytes */
 static u32 ddr3_tip_compare(u32 if_id, u32 *p_src, u32 *p_dst,
 			    u32 byte_index)
@@ -1182,7 +1277,7 @@ static u32 ddr3_tip_compare(u32 if_id, u32 *p_src, u32 *p_dst,
 		 0xff) ? (u32) 0xffffffff : (u32) (0xff << (byte_index * 8));
 	for (burst_cnt = 0; burst_cnt < EXT_ACCESS_BURST_LENGTH; burst_cnt++) {
 		if ((p_src[burst_cnt] & addr_offset) !=
-		    (p_dst[burst_cnt] & addr_offset))
+		    (p_dst[if_id] & addr_offset))
 			b_is_fail = 1;
 	}
 
@@ -1204,69 +1299,9 @@ static u32 ddr3_tip_compare(u32 if_id, u32 *p_src, u32 *p_dst,
 
 	return b_is_fail;
 }
+#endif /* EXCLUDE_SWITCH_DEBUG */
 
-/* test_type = 0-tx , 1-rx */
-int ddr3_tip_sweep_test(u32 dev_num, u32 test_type,
-			u32 mem_addr, u32 is_modify_adll,
-			u32 start_if, u32 end_if, u32 startpup, u32 endpup)
-{
-	u32 bus_cnt = 0, adll_val = 0, if_id, ui_prev_adll, ui_mask_bit,
-		end_adll, start_adll;
-	u32 reg_addr = 0;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
-
-	if (test_type == 0) {
-		reg_addr = 1;
-		ui_mask_bit = 0x3f;
-		start_adll = 0;
-		end_adll = ui_mask_bit;
-	} else {
-		reg_addr = 3;
-		ui_mask_bit = 0x1f;
-		start_adll = 0;
-		end_adll = ui_mask_bit;
-	}
-
-	DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
-			  ("==============================\n"));
-	DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
-			  ("Test type %d (0-tx, 1-rx)\n", test_type));
-
-	for (if_id = start_if; if_id <= end_if; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-		for (bus_cnt = startpup; bus_cnt < endpup; bus_cnt++) {
-			CHECK_STATUS(ddr3_tip_bus_read
-				     (dev_num, if_id, ACCESS_TYPE_UNICAST,
-				      bus_cnt, DDR_PHY_DATA, reg_addr,
-				      &ui_prev_adll));
-
-			for (adll_val = start_adll; adll_val <= end_adll;
-			     adll_val++) {
-				if (is_modify_adll == 1) {
-					CHECK_STATUS(ddr3_tip_bus_read_modify_write
-						     (dev_num,
-						      ACCESS_TYPE_UNICAST,
-						      if_id, bus_cnt,
-						      DDR_PHY_DATA, reg_addr,
-						      adll_val, ui_mask_bit));
-				}
-			}
-			if (is_modify_adll == 1) {
-				CHECK_STATUS(ddr3_tip_bus_write
-					     (dev_num, ACCESS_TYPE_UNICAST,
-					      if_id, ACCESS_TYPE_UNICAST,
-					      bus_cnt, DDR_PHY_DATA, reg_addr,
-					      ui_prev_adll));
-			}
-			DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("\n"));
-		}
-		DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("\n"));
-	}
-
-	return MV_OK;
-}
-
-#ifndef EXCLUDE_SWITCH_DEBUG
+#if defined(DDR_VIEWER_TOOL)
 /*
  * Sweep validation
  */
@@ -1274,21 +1309,23 @@ int ddr3_tip_run_sweep_test(int dev_num, u32 repeat_num, u32 direction,
 			    u32 mode)
 {
 	u32 pup = 0, start_pup = 0, end_pup = 0;
-	u32 adll = 0;
+	u32 adll = 0, rep = 0, pattern_idx = 0;
 	u32 res[MAX_INTERFACE_NUM] = { 0 };
 	int if_id = 0;
 	u32 adll_value = 0;
-	int reg = (direction == 0) ? WRITE_CENTRALIZATION_PHY_REG :
-		READ_CENTRALIZATION_PHY_REG;
+	u32 reg;
 	enum hws_access_type pup_access;
 	u32 cs;
-	u32 max_cs = hws_ddr3_tip_max_cs_get();
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 max_cs = ddr3_tip_max_cs_get(dev_num);
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+
+	repeat_num = 2;
 
 	if (mode == 1) {
 		/* per pup */
 		start_pup = 0;
-		end_pup = tm->num_of_bus_per_interface - 1;
+		end_pup = octets_per_if_num - 1;
 		pup_access = ACCESS_TYPE_UNICAST;
 	} else {
 		start_pup = 0;
@@ -1297,11 +1334,12 @@ int ddr3_tip_run_sweep_test(int dev_num, u32 repeat_num, u32 direction,
 	}
 
 	for (cs = 0; cs < max_cs; cs++) {
+		reg = (direction == 0) ? CTX_PHY_REG(cs) : CRX_PHY_REG(cs);
 		for (adll = 0; adll < ADLL_LENGTH; adll++) {
 			for (if_id = 0;
 			     if_id <= MAX_INTERFACE_NUM - 1;
 			     if_id++) {
-				VALIDATE_ACTIVE
+				VALIDATE_IF_ACTIVE
 					(tm->if_act_mask,
 					 if_id);
 				for (pup = start_pup; pup <= end_pup; pup++) {
@@ -1313,10 +1351,9 @@ int ddr3_tip_run_sweep_test(int dev_num, u32 repeat_num, u32 direction,
 
 		for (adll = 0; adll < (MAX_INTERFACE_NUM * MAX_BUS_NUM); adll++)
 			ctrl_adll[adll] = 0;
-		/* Save DQS value(after algorithm run) */
-		read_adll_value(ctrl_adll,
-				(reg + (cs * CS_REGISTER_ADDR_OFFSET)),
-				MASK_ALL_BITS);
+			/* Save DQS value(after algorithm run) */
+			ddr3_tip_read_adll_value(dev_num, ctrl_adll,
+						 reg, MASK_ALL_BITS);
 
 		/*
 		 * Sweep ADLL  from 0:31 on all I/F on all Pup and perform
@@ -1324,38 +1361,43 @@ int ddr3_tip_run_sweep_test(int dev_num, u32 repeat_num, u32 direction,
 		 */
 		for (pup = start_pup; pup <= end_pup; pup++) {
 			for (adll = 0; adll < ADLL_LENGTH; adll++) {
-				adll_value =
-					(direction == 0) ? (adll * 2) : adll;
-				CHECK_STATUS(ddr3_tip_bus_write
-					     (dev_num, ACCESS_TYPE_MULTICAST, 0,
-					      pup_access, pup, DDR_PHY_DATA,
-					      reg + CS_REG_VALUE(cs),
-					      adll_value));
-				hws_ddr3_run_bist(dev_num, sweep_pattern, res,
-						  cs);
-				/* ddr3_tip_reset_fifo_ptr(dev_num); */
-				for (if_id = 0;
-				     if_id <= MAX_INTERFACE_NUM - 1;
-				     if_id++) {
-					VALIDATE_ACTIVE
-						(tm->if_act_mask,
-						 if_id);
-					ctrl_sweepres[adll][if_id][pup]
-						= res[if_id];
-					if (mode == 1) {
-						CHECK_STATUS
-							(ddr3_tip_bus_write
-							 (dev_num,
-							  ACCESS_TYPE_UNICAST,
-							  if_id,
-							  ACCESS_TYPE_UNICAST,
-							  pup,
-							  DDR_PHY_DATA,
-							  reg + CS_REG_VALUE(cs),
-							  ctrl_adll[if_id *
-								    cs *
-								    tm->num_of_bus_per_interface
-								    + pup]));
+				for (rep = 0; rep < repeat_num; rep++) {
+					for (pattern_idx = PATTERN_KILLER_DQ0;
+					     pattern_idx < PATTERN_LAST;
+					     pattern_idx++) {
+						adll_value =
+							(direction == 0) ? (adll * 2) : adll;
+						CHECK_STATUS(ddr3_tip_bus_write
+							     (dev_num, ACCESS_TYPE_MULTICAST, 0,
+							      pup_access, pup, DDR_PHY_DATA,
+							      reg, adll_value));
+						hws_ddr3_run_bist(dev_num, sweep_pattern, res,
+								  cs);
+						/* ddr3_tip_reset_fifo_ptr(dev_num); */
+						for (if_id = 0;
+						     if_id < MAX_INTERFACE_NUM;
+						     if_id++) {
+							VALIDATE_IF_ACTIVE
+								(tm->if_act_mask,
+								 if_id);
+							ctrl_sweepres[adll][if_id][pup]
+								+= res[if_id];
+							if (mode == 1) {
+								CHECK_STATUS
+									(ddr3_tip_bus_write
+									 (dev_num,
+									  ACCESS_TYPE_UNICAST,
+									  if_id,
+									  ACCESS_TYPE_UNICAST,
+									  pup,
+									  DDR_PHY_DATA,
+									  reg,
+									  ctrl_adll[if_id *
+										    cs *
+										    octets_per_if_num
+										    + pup]));
+							}
+						}
 					}
 				}
 			}
@@ -1363,10 +1405,10 @@ int ddr3_tip_run_sweep_test(int dev_num, u32 repeat_num, u32 direction,
 		printf("Final, CS %d,%s, Sweep, Result, Adll,", cs,
 		       ((direction == 0) ? "TX" : "RX"));
 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 			if (mode == 1) {
 				for (pup = start_pup; pup <= end_pup; pup++) {
-					VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+					VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup);
 					printf("I/F%d-PHY%d , ", if_id, pup);
 				}
 			} else {
@@ -1383,9 +1425,9 @@ int ddr3_tip_run_sweep_test(int dev_num, u32 repeat_num, u32 direction,
 			for (if_id = 0;
 			     if_id <= MAX_INTERFACE_NUM - 1;
 			     if_id++) {
-				VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+				VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 				for (pup = start_pup; pup <= end_pup; pup++) {
-					printf("%d , ",
+					printf("%8d , ",
 					       ctrl_sweepres[adll][if_id]
 					       [pup]);
 				}
@@ -1397,11 +1439,9 @@ int ddr3_tip_run_sweep_test(int dev_num, u32 repeat_num, u32 direction,
 		 * Write back to the phy the Rx DQS value, we store in
 		 * the beginning.
 		 */
-		write_adll_value(ctrl_adll,
-				 (reg + cs * CS_REGISTER_ADDR_OFFSET));
+		ddr3_tip_write_adll_value(dev_num, ctrl_adll, reg);
 		/* print adll results */
-		read_adll_value(ctrl_adll, (reg + cs * CS_REGISTER_ADDR_OFFSET),
-				MASK_ALL_BITS);
+		ddr3_tip_read_adll_value(dev_num, ctrl_adll, reg, MASK_ALL_BITS);
 		printf("%s, DQS, ADLL,,,", (direction == 0) ? "Tx" : "Rx");
 		print_adll(dev_num, ctrl_adll);
 	}
@@ -1410,16 +1450,214 @@ int ddr3_tip_run_sweep_test(int dev_num, u32 repeat_num, u32 direction,
 	return 0;
 }
 
-void print_topology(struct hws_topology_map *topology_db)
+#if defined(EXCLUDE_SWITCH_DEBUG)
+int ddr3_tip_run_leveling_sweep_test(int dev_num, u32 repeat_num,
+				     u32 direction, u32 mode)
+{
+	u32 pup = 0, start_pup = 0, end_pup = 0, start_adll = 0;
+	u32 adll = 0, rep = 0, pattern_idx = 0;
+	u32 read_data[MAX_INTERFACE_NUM];
+	u32 res[MAX_INTERFACE_NUM] = { 0 };
+	int if_id = 0, gap = 0;
+	u32 adll_value = 0;
+	u32 reg;
+	enum hws_access_type pup_access;
+	u32 cs;
+	u32 max_cs = ddr3_tip_max_cs_get(dev_num);
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+
+	if (mode == 1) { /* per pup */
+		start_pup = 0;
+		end_pup = octets_per_if_num - 1;
+		pup_access = ACCESS_TYPE_UNICAST;
+	} else {
+		start_pup = 0;
+		end_pup = 0;
+		pup_access = ACCESS_TYPE_MULTICAST;
+	}
+
+	for (cs = 0; cs < max_cs; cs++) {
+		reg = (direction == 0) ? WL_PHY_REG(cs) : RL_PHY_REG(cs);
+		for (adll = 0; adll < ADLL_LENGTH; adll++) {
+			for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
+				VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+				for (pup = start_pup; pup <= end_pup; pup++)
+					ctrl_sweepres[adll][if_id][pup] = 0;
+			}
+		}
+
+		for (adll = 0; adll < MAX_INTERFACE_NUM * MAX_BUS_NUM; adll++) {
+			ctrl_adll[adll] = 0;
+			ctrl_level_phase[adll] = 0;
+			ctrl_adll1[adll] = 0;
+		}
+
+		/* save leveling value after running algorithm */
+		ddr3_tip_read_adll_value(dev_num, ctrl_adll, reg, 0x1f);
+		read_phase_value(dev_num, ctrl_level_phase, reg, 0x7 << 6);
+
+		if (direction == 0)
+			ddr3_tip_read_adll_value(dev_num, ctrl_adll1,
+						 CTX_PHY_REG(cs), MASK_ALL_BITS);
+
+		/* Sweep ADLL from 0 to 31 on all interfaces, all pups,
+		 * and perform BIST on each stage
+		 */
+		for (pup = start_pup; pup <= end_pup; pup++) {
+			for (adll = 0; adll < ADLL_LENGTH; adll++) {
+				for (rep = 0; rep < repeat_num; rep++) {
+					adll_value = (direction == 0) ? (adll * 2) : (adll * 3);
+					for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+						start_adll = ctrl_adll[if_id * cs * octets_per_if_num + pup] +
+							     (ctrl_level_phase[if_id * cs *
+									     octets_per_if_num +
+									     pup] >> 6) * 32;
+
+						if (direction == 0)
+							start_adll = (start_adll > 32) ? (start_adll - 32) : 0;
+						else
+							start_adll = (start_adll > 48) ? (start_adll - 48) : 0;
+
+						adll_value += start_adll;
+
+						gap = ctrl_adll1[if_id * cs * octets_per_if_num + pup] -
+						      ctrl_adll[if_id * cs * octets_per_if_num + pup];
+						gap = (((adll_value % 32) + gap) % 64);
+
+						adll_value = ((adll_value % 32) +
+							       (((adll_value - (adll_value % 32)) / 32) << 6));
+
+						CHECK_STATUS(ddr3_tip_bus_write(dev_num,
+										ACCESS_TYPE_UNICAST,
+										if_id,
+										pup_access,
+										pup,
+										DDR_PHY_DATA,
+										reg,
+										adll_value));
+						if (direction == 0)
+							CHECK_STATUS(ddr3_tip_bus_write(dev_num,
+											ACCESS_TYPE_UNICAST,
+											if_id,
+											pup_access,
+											pup,
+											DDR_PHY_DATA,
+											CTX_PHY_REG(cs),
+											gap));
+					}
+
+					for (pattern_idx = PATTERN_KILLER_DQ0;
+					     pattern_idx < PATTERN_LAST;
+					     pattern_idx++) {
+						hws_ddr3_run_bist(dev_num, sweep_pattern, res, cs);
+						ddr3_tip_reset_fifo_ptr(dev_num);
+						for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+							VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+							if (pup != 4) { /* TODO: remove literal */
+								ctrl_sweepres[adll][if_id][pup] += res[if_id];
+							} else {
+								CHECK_STATUS(ddr3_tip_if_read(dev_num,
+											      ACCESS_TYPE_UNICAST,
+											      if_id,
+											      0x1458,
+											      read_data,
+											      MASK_ALL_BITS));
+								ctrl_sweepres[adll][if_id][pup] += read_data[if_id];
+								CHECK_STATUS(ddr3_tip_if_write(dev_num,
+											       ACCESS_TYPE_UNICAST,
+											       if_id,
+											       0x1458,
+											       0x0,
+											       0xFFFFFFFF));
+								CHECK_STATUS(ddr3_tip_if_write(dev_num,
+											       ACCESS_TYPE_UNICAST,
+											       if_id,
+											       0x145C,
+											       0x0,
+											       0xFFFFFFFF));
+							}
+						}
+					}
+				}
+			}
+
+			for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+				start_adll = ctrl_adll[if_id * cs * octets_per_if_num + pup] +
+					     ctrl_level_phase[if_id * cs * octets_per_if_num + pup];
+				CHECK_STATUS(ddr3_tip_bus_write(dev_num, ACCESS_TYPE_UNICAST, if_id, pup_access, pup,
+								DDR_PHY_DATA, reg, start_adll));
+				if (direction == 0)
+					CHECK_STATUS(ddr3_tip_bus_write(dev_num,
+									ACCESS_TYPE_UNICAST,
+									if_id,
+									pup_access,
+									pup,
+									DDR_PHY_DATA,
+									CTX_PHY_REG(cs),
+									ctrl_adll1[if_id *
+										   cs *
+										   octets_per_if_num +
+										   pup]));
+			}
+		}
+
+		printf("Final,CS %d,%s,Leveling,Result,Adll,", cs, ((direction == 0) ? "TX" : "RX"));
+
+		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+			if (mode == 1) {
+				for (pup = start_pup; pup <= end_pup; pup++) {
+					VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup);
+					printf("I/F%d-PHY%d , ", if_id, pup);
+				}
+			} else {
+				printf("I/F%d , ", if_id);
+			}
+		}
+		printf("\n");
+
+		for (adll = 0; adll < ADLL_LENGTH; adll++) {
+			adll_value = (direction == 0) ? ((adll * 2) - 32) : ((adll * 3) - 48);
+			printf("Final,%s,LevelingSweep,Result, %d ,", ((direction == 0) ? "TX" : "RX"), adll_value);
+
+			for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+				VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+				for (pup = start_pup; pup <= end_pup; pup++)
+					printf("%8d , ", ctrl_sweepres[adll][if_id][pup]);
+			}
+			printf("\n");
+		}
+
+		/* write back to the phy the Rx DQS value, we store in the beginning */
+		write_leveling_value(dev_num, ctrl_adll, ctrl_level_phase, reg);
+		if (direction == 0)
+			ddr3_tip_write_adll_value(dev_num, ctrl_adll1, CTX_PHY_REG(cs));
+
+		/* print adll results */
+		ddr3_tip_read_adll_value(dev_num, ctrl_adll, reg, MASK_ALL_BITS);
+		printf("%s,DQS,Leveling,,,", (direction == 0) ? "Tx" : "Rx");
+		print_adll(dev_num, ctrl_adll);
+		print_ph(dev_num, ctrl_level_phase);
+	}
+	ddr3_tip_reset_fifo_ptr(dev_num);
+
+	return 0;
+}
+#endif /* EXCLUDE_SWITCH_DEBUG */
+
+void print_topology(struct mv_ddr_topology_map *topology_db)
 {
 	u32 ui, uj;
+	u32 dev_num = 0;
 
 	printf("\tinterface_mask: 0x%x\n", topology_db->if_act_mask);
-	printf("\tNum Bus:  %d\n", topology_db->num_of_bus_per_interface);
+	printf("\tNumber of buses: 0x%x\n",
+	       ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE));
 	printf("\tbus_act_mask: 0x%x\n", topology_db->bus_act_mask);
 
 	for (ui = 0; ui < MAX_INTERFACE_NUM; ui++) {
-		VALIDATE_ACTIVE(topology_db->if_act_mask, ui);
+		VALIDATE_IF_ACTIVE(topology_db->if_act_mask, ui);
 		printf("\n\tInterface ID: %d\n", ui);
 		printf("\t\tDDR Frequency: %s\n",
 		       convert_freq(topology_db->
@@ -1457,8 +1695,9 @@ void print_topology(struct hws_topology_map *topology_db)
 		}
 	}
 }
-#endif
+#endif /* DDR_VIEWER_TOOL */
 
+#if !defined(EXCLUDE_SWITCH_DEBUG)
 /*
  * Execute XSB Test transaction (rd/wr/both)
  */
@@ -1468,10 +1707,10 @@ int run_xsb_test(u32 dev_num, u32 mem_addr, u32 write_type,
 	u32 seq = 0, if_id = 0, addr, cnt;
 	int ret = MV_OK, ret_tmp;
 	u32 data_read[MAX_INTERFACE_NUM];
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		addr = mem_addr;
 		for (cnt = 0; cnt <= burst_length; cnt++) {
 			seq = (seq + 1) % 8;
@@ -1501,13 +1740,7 @@ int run_xsb_test(u32 dev_num, u32 mem_addr, u32 write_type,
 }
 
 #else /*EXCLUDE_SWITCH_DEBUG */
-
-u32 rl_version = 1;		/* 0 - old RL machine */
-u32 vref = 0x4;
 u32 start_xsb_offset = 0;
-u8 cs_mask_reg[] = {
-	0, 4, 8, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
 
 int run_xsb_test(u32 dev_num, u32 mem_addr, u32 write_type,
 		 u32 read_type, u32 burst_length)
@@ -1515,4 +1748,4 @@ int run_xsb_test(u32 dev_num, u32 mem_addr, u32 write_type,
 	return MV_OK;
 }
 
-#endif
+#endif /* EXCLUDE_SWITCH_DEBUG */
diff --git a/drivers/ddr/marvell/a38x/ddr3_hws_hw_training.c b/drivers/ddr/marvell/a38x/ddr3_hws_hw_training.c
deleted file mode 100644
index 560da7ee80b6..000000000000
--- a/drivers/ddr/marvell/a38x/ddr3_hws_hw_training.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- *
- * SPDX-License-Identifier:	GPL-2.0
- */
-
-#include <common.h>
-#include <i2c.h>
-#include <spl.h>
-#include <asm/io.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/soc.h>
-
-#include "ddr3_init.h"
-
-#define REG_READ_DATA_SAMPLE_DELAYS_ADDR	0x1538
-#define REG_READ_DATA_SAMPLE_DELAYS_MASK	0x1f
-#define REG_READ_DATA_SAMPLE_DELAYS_OFFS	8
-
-#define REG_READ_DATA_READY_DELAYS_ADDR		0x153c
-#define REG_READ_DATA_READY_DELAYS_MASK		0x1f
-#define REG_READ_DATA_READY_DELAYS_OFFS		8
-
-int ddr3_if_ecc_enabled(void)
-{
-	struct hws_topology_map *tm = ddr3_get_topology_map();
-
-	if (DDR3_IS_ECC_PUP4_MODE(tm->bus_act_mask) ||
-	    DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask))
-		return 1;
-	else
-		return 0;
-}
-
-int ddr3_pre_algo_config(void)
-{
-	struct hws_topology_map *tm = ddr3_get_topology_map();
-
-	/* Set Bus3 ECC training mode */
-	if (DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask)) {
-		/* Set Bus3 ECC MUX */
-		CHECK_STATUS(ddr3_tip_if_write
-			     (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE,
-			      REG_SDRAM_PINS_MUX, 0x100, 0x100));
-	}
-
-	/* Set regular ECC training mode (bus4 and bus 3) */
-	if ((DDR3_IS_ECC_PUP4_MODE(tm->bus_act_mask)) ||
-	    (DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask))) {
-		/* Enable ECC Write MUX */
-		CHECK_STATUS(ddr3_tip_if_write
-			     (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE,
-			      TRAINING_SW_2_REG, 0x100, 0x100));
-		/* General ECC enable */
-		CHECK_STATUS(ddr3_tip_if_write
-			     (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE,
-			      REG_SDRAM_CONFIG_ADDR, 0x40000, 0x40000));
-		/* Disable Read Data ECC MUX */
-		CHECK_STATUS(ddr3_tip_if_write
-			     (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE,
-			      TRAINING_SW_2_REG, 0x0, 0x2));
-	}
-
-	return MV_OK;
-}
-
-int ddr3_post_algo_config(void)
-{
-	struct hws_topology_map *tm = ddr3_get_topology_map();
-	int status;
-
-	status = ddr3_post_run_alg();
-	if (MV_OK != status) {
-		printf("DDR3 Post Run Alg - FAILED 0x%x\n", status);
-		return status;
-	}
-
-	/* Un_set ECC training mode */
-	if ((DDR3_IS_ECC_PUP4_MODE(tm->bus_act_mask)) ||
-	    (DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask))) {
-		/* Disable ECC Write MUX */
-		CHECK_STATUS(ddr3_tip_if_write
-			     (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE,
-			      TRAINING_SW_2_REG, 0x0, 0x100));
-		/* General ECC and Bus3 ECC MUX remains enabled */
-	}
-
-	return MV_OK;
-}
-
-int ddr3_hws_hw_training(void)
-{
-	enum hws_algo_type algo_mode = ALGO_TYPE_DYNAMIC;
-	int status;
-	struct init_cntr_param init_param;
-
-	status = ddr3_silicon_pre_init();
-	if (MV_OK != status) {
-		printf("DDR3 Pre silicon Config - FAILED 0x%x\n", status);
-		return status;
-	}
-
-	init_param.do_mrs_phy = 1;
-#if defined(CONFIG_ARMADA_38X)  || defined(CONFIG_ARMADA_39X)
-	init_param.is_ctrl64_bit = 0;
-#else
-	init_param.is_ctrl64_bit = 1;
-#endif
-#if defined(CONFIG_ALLEYCAT3) || defined(CONFIG_ARMADA_38X) || \
-	defined(CONFIG_ARMADA_39X)
-	init_param.init_phy = 1;
-#else
-	init_param.init_phy = 0;
-#endif
-	init_param.msys_init = 1;
-	status = hws_ddr3_tip_init_controller(0, &init_param);
-	if (MV_OK != status) {
-		printf("DDR3 init controller - FAILED 0x%x\n", status);
-		return status;
-	}
-
-	status = ddr3_silicon_post_init();
-	if (MV_OK != status) {
-		printf("DDR3 Post Init - FAILED 0x%x\n", status);
-		return status;
-	}
-
-	status = ddr3_pre_algo_config();
-	if (MV_OK != status) {
-		printf("DDR3 Pre Algo Config - FAILED 0x%x\n", status);
-		return status;
-	}
-
-	/* run algorithm in order to configure the PHY */
-	status = hws_ddr3_tip_run_alg(0, algo_mode);
-	if (MV_OK != status) {
-		printf("DDR3 run algorithm - FAILED 0x%x\n", status);
-		return status;
-	}
-
-	status = ddr3_post_algo_config();
-	if (MV_OK != status) {
-		printf("DDR3 Post Algo Config - FAILED 0x%x\n", status);
-		return status;
-	}
-
-	return MV_OK;
-}
diff --git a/drivers/ddr/marvell/a38x/ddr3_hws_hw_training.h b/drivers/ddr/marvell/a38x/ddr3_hws_hw_training.h
deleted file mode 100644
index 17a09530d703..000000000000
--- a/drivers/ddr/marvell/a38x/ddr3_hws_hw_training.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- *
- * SPDX-License-Identifier:	GPL-2.0
- */
-
-#ifndef _DDR3_HWS_HW_TRAINING_H
-#define _DDR3_HWS_HW_TRAINING_H
-
-/* struct used for DLB configuration array */
-struct dlb_config {
-	u32 reg_addr;
-	u32 reg_data;
-};
-
-/* Topology update structure */
-struct topology_update_info {
-	int	update_ecc;
-	u8	ecc;
-	int	update_width;
-	u8	width;
-	int	update_ecc_pup3_mode;
-	u8	ecc_pup_mode_offset;
-};
-
-/* Topology update defines */
-#define TOPOLOGY_UPDATE_WIDTH_16BIT		1
-#define TOPOLOGY_UPDATE_WIDTH_32BIT		0
-#define TOPOLOGY_UPDATE_WIDTH_32BIT_MASK	0xf
-#define TOPOLOGY_UPDATE_WIDTH_16BIT_MASK	0x3
-
-#define TOPOLOGY_UPDATE_ECC_ON			1
-#define TOPOLOGY_UPDATE_ECC_OFF			0
-#define TOPOLOGY_UPDATE_ECC_OFFSET_PUP4		4
-#define TOPOLOGY_UPDATE_ECC_OFFSET_PUP3		3
-
-/*
- * 1. L2 filter should be set at binary header to 0xd000000,
- *    to avoid conflict with internal register IO.
- * 2. U-Boot modifies internal registers base to 0xf100000,
- *    and than should update L2 filter accordingly to 0xf000000 (3.75 GB)
- */
-/* temporary limit l2 filter to 3GiB (LSP issue) */
-#define L2_FILTER_FOR_MAX_MEMORY_SIZE 0xc0000000
-#define ADDRESS_FILTERING_END_REGISTER 0x8c04
-
-#define SUB_VERSION	0
-
-#endif /* _DDR3_HWS_HW_TRAINING_H */
diff --git a/drivers/ddr/marvell/a38x/ddr3_hws_hw_training_def.h b/drivers/ddr/marvell/a38x/ddr3_hws_hw_training_def.h
deleted file mode 100644
index bca0af89a72d..000000000000
--- a/drivers/ddr/marvell/a38x/ddr3_hws_hw_training_def.h
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- *
- * SPDX-License-Identifier:	GPL-2.0
- */
-
-#ifndef _DDR3_HWS_HW_TRAINING_DEF_H
-#define _DDR3_HWS_HW_TRAINING_DEF_H
-
-#define SAR_DDR3_FREQ_MASK		0xfe00000
-#define SAR_CPU_FAB_GET(cpu, fab)	(((cpu & 0x7) << 21) | \
-					 ((fab & 0xf) << 24))
-
-#define MAX_CS				4
-
-#define MIN_DIMM_ADDR			0x50
-#define FAR_END_DIMM_ADDR		0x50
-#define MAX_DIMM_ADDR			0x60
-
-#define SDRAM_CS_SIZE			0xfffffff
-#define SDRAM_CS_BASE			0x0
-#define SDRAM_DIMM_SIZE			0x80000000
-
-#define CPU_CONFIGURATION_REG(id)	(0x21800 + (id * 0x100))
-#define CPU_MRVL_ID_OFFSET		0x10
-#define SAR1_CPU_CORE_MASK		0x38000000
-#define SAR1_CPU_CORE_OFFSET		27
-
-#define NEW_FABRIC_TWSI_ADDR		0x4e
-#ifdef DB_784MP_GP
-#define BUS_WIDTH_ECC_TWSI_ADDR		0x4e
-#else
-#define BUS_WIDTH_ECC_TWSI_ADDR		0x4f
-#endif
-#define MV_MAX_DDR3_STATIC_SIZE		50
-#define MV_DDR3_MODES_NUMBER		30
-
-#define RESUME_RL_PATTERNS_ADDR		0xfe0000
-#define RESUME_RL_PATTERNS_SIZE		0x100
-#define RESUME_TRAINING_VALUES_ADDR	(RESUME_RL_PATTERNS_ADDR + \
-					 RESUME_RL_PATTERNS_SIZE)
-#define RESUME_TRAINING_VALUES_MAX	0xcd0
-#define BOOT_INFO_ADDR			(RESUME_RL_PATTERNS_ADDR + 0x1000)
-#define CHECKSUM_RESULT_ADDR		(BOOT_INFO_ADDR + 0x1000)
-#define NUM_OF_REGISTER_ADDR		(CHECKSUM_RESULT_ADDR + 4)
-#define SUSPEND_MAGIC_WORD		0xdeadb002
-#define REGISTER_LIST_END		0xffffffff
-
-/* MISC */
-#define INTER_REGS_BASE			SOC_REGS_PHY_BASE
-
-/* DDR */
-#define REG_SDRAM_CONFIG_ADDR			0x1400
-#define REG_SDRAM_CONFIG_MASK			0x9fffffff
-#define REG_SDRAM_CONFIG_RFRS_MASK		0x3fff
-#define REG_SDRAM_CONFIG_WIDTH_OFFS		15
-#define REG_SDRAM_CONFIG_REGDIMM_OFFS		17
-#define REG_SDRAM_CONFIG_ECC_OFFS		18
-#define REG_SDRAM_CONFIG_IERR_OFFS		19
-#define REG_SDRAM_CONFIG_PUPRSTDIV_OFFS		28
-#define REG_SDRAM_CONFIG_RSTRD_OFFS		30
-
-#define REG_SDRAM_PINS_MUX			0x19d4
-
-#define REG_DUNIT_CTRL_LOW_ADDR			0x1404
-#define REG_DUNIT_CTRL_LOW_2T_OFFS		3
-#define REG_DUNIT_CTRL_LOW_2T_MASK		0x3
-#define REG_DUNIT_CTRL_LOW_DPDE_OFFS		14
-
-#define REG_SDRAM_TIMING_LOW_ADDR		0x1408
-#define REG_SDRAM_TIMING_HIGH_ADDR		0x140c
-#define REG_SDRAM_TIMING_H_R2R_OFFS		7
-#define REG_SDRAM_TIMING_H_R2R_MASK		0x3
-#define REG_SDRAM_TIMING_H_R2W_W2R_OFFS		9
-#define REG_SDRAM_TIMING_H_R2W_W2R_MASK		0x3
-#define REG_SDRAM_TIMING_H_W2W_OFFS		11
-#define REG_SDRAM_TIMING_H_W2W_MASK		0x1f
-#define REG_SDRAM_TIMING_H_R2R_H_OFFS		19
-#define REG_SDRAM_TIMING_H_R2R_H_MASK		0x7
-#define REG_SDRAM_TIMING_H_R2W_W2R_H_OFFS	22
-#define REG_SDRAM_TIMING_H_R2W_W2R_H_MASK	0x7
-
-#define REG_SDRAM_ADDRESS_CTRL_ADDR		0x1410
-#define REG_SDRAM_ADDRESS_SIZE_OFFS		2
-#define REG_SDRAM_ADDRESS_SIZE_HIGH_OFFS	18
-#define REG_SDRAM_ADDRESS_CTRL_STRUCT_OFFS	4
-
-#define REG_SDRAM_OPEN_PAGES_ADDR		0x1414
-#define REG_SDRAM_OPERATION_CS_OFFS		8
-
-#define REG_SDRAM_OPERATION_ADDR		0x1418
-#define REG_SDRAM_OPERATION_CWA_DELAY_SEL_OFFS	24
-#define REG_SDRAM_OPERATION_CWA_DATA_OFFS	20
-#define REG_SDRAM_OPERATION_CWA_DATA_MASK	0xf
-#define REG_SDRAM_OPERATION_CWA_RC_OFFS		16
-#define REG_SDRAM_OPERATION_CWA_RC_MASK		0xf
-#define REG_SDRAM_OPERATION_CMD_MR0		0xf03
-#define REG_SDRAM_OPERATION_CMD_MR1		0xf04
-#define REG_SDRAM_OPERATION_CMD_MR2		0xf08
-#define REG_SDRAM_OPERATION_CMD_MR3		0xf09
-#define REG_SDRAM_OPERATION_CMD_RFRS		0xf02
-#define REG_SDRAM_OPERATION_CMD_CWA		0xf0e
-#define REG_SDRAM_OPERATION_CMD_RFRS_DONE	0xf
-#define REG_SDRAM_OPERATION_CMD_MASK		0xf
-#define REG_SDRAM_OPERATION_CS_OFFS		8
-
-#define REG_OUDDR3_TIMING_ADDR			0x142c
-
-#define REG_SDRAM_MODE_ADDR			0x141c
-
-#define REG_SDRAM_EXT_MODE_ADDR			0x1420
-
-#define REG_DDR_CONT_HIGH_ADDR			0x1424
-
-#define REG_ODT_TIME_LOW_ADDR			0x1428
-#define REG_ODT_ON_CTL_RD_OFFS                  12
-#define REG_ODT_OFF_CTL_RD_OFFS                 16
-#define REG_SDRAM_ERROR_ADDR                    0x1454
-#define REG_SDRAM_AUTO_PWR_SAVE_ADDR            0x1474
-#define REG_ODT_TIME_HIGH_ADDR			0x147c
-
-#define REG_SDRAM_INIT_CTRL_ADDR		0x1480
-#define REG_SDRAM_INIT_CTRL_OFFS		0
-#define REG_SDRAM_INIT_CKE_ASSERT_OFFS		2
-#define REG_SDRAM_INIT_RESET_DEASSERT_OFFS	3
-#define REG_SDRAM_INIT_RESET_MASK_OFFS		1
-
-#define REG_SDRAM_ODT_CTRL_LOW_ADDR		0x1494
-
-#define REG_SDRAM_ODT_CTRL_HIGH_ADDR		0x1498
-#define REG_SDRAM_ODT_CTRL_HIGH_OVRD_MASK	0x0
-#define REG_SDRAM_ODT_CTRL_HIGH_OVRD_ENA	0x3
-
-#define REG_DUNIT_ODT_CTRL_ADDR			0x149c
-#define REG_DUNIT_ODT_CTRL_OVRD_OFFS            8
-#define REG_DUNIT_ODT_CTRL_OVRD_VAL_OFFS        9
-
-#define REG_DRAM_FIFO_CTRL_ADDR			0x14a0
-
-#define REG_DRAM_AXI_CTRL_ADDR			0x14a8
-#define REG_DRAM_AXI_CTRL_AXIDATABUSWIDTH_OFFS	0
-
-#define REG_METAL_MASK_ADDR			0x14b0
-#define REG_METAL_MASK_MASK			0xdfffffff
-#define REG_METAL_MASK_RETRY_OFFS		0
-
-#define REG_DRAM_ADDR_CTRL_DRIVE_STRENGTH_ADDR	0x14c0
-
-#define REG_DRAM_DATA_DQS_DRIVE_STRENGTH_ADDR	0x14c4
-#define REG_DRAM_VER_CAL_MACHINE_CTRL_ADDR      0x14c8
-#define REG_DRAM_MAIN_PADS_CAL_ADDR		0x14cc
-
-#define REG_DRAM_HOR_CAL_MACHINE_CTRL_ADDR      0x17c8
-
-#define REG_CS_SIZE_SCRATCH_ADDR		0x1504
-#define REG_DYNAMIC_POWER_SAVE_ADDR             0x1520
-#define REG_DDR_IO_ADDR				0x1524
-#define REG_DDR_IO_CLK_RATIO_OFFS		15
-
-#define REG_DFS_ADDR				0x1528
-#define REG_DFS_DLLNEXTSTATE_OFFS		0
-#define REG_DFS_BLOCK_OFFS			1
-#define REG_DFS_SR_OFFS				2
-#define REG_DFS_ATSR_OFFS			3
-#define REG_DFS_RECONF_OFFS			4
-#define REG_DFS_CL_NEXT_STATE_OFFS		8
-#define REG_DFS_CL_NEXT_STATE_MASK		0xf
-#define REG_DFS_CWL_NEXT_STATE_OFFS		12
-#define REG_DFS_CWL_NEXT_STATE_MASK		0x7
-
-#define REG_READ_DATA_SAMPLE_DELAYS_ADDR	0x1538
-#define REG_READ_DATA_SAMPLE_DELAYS_MASK	0x1f
-#define REG_READ_DATA_SAMPLE_DELAYS_OFFS	8
-
-#define REG_READ_DATA_READY_DELAYS_ADDR		0x153c
-#define REG_READ_DATA_READY_DELAYS_MASK		0x1f
-#define REG_READ_DATA_READY_DELAYS_OFFS		8
-
-#define START_BURST_IN_ADDR			1
-
-#define REG_DRAM_TRAINING_SHADOW_ADDR		0x18488
-#define REG_DRAM_TRAINING_ADDR			0x15b0
-#define REG_DRAM_TRAINING_LOW_FREQ_OFFS		0
-#define REG_DRAM_TRAINING_PATTERNS_OFFS		4
-#define REG_DRAM_TRAINING_MED_FREQ_OFFS		2
-#define REG_DRAM_TRAINING_WL_OFFS		3
-#define REG_DRAM_TRAINING_RL_OFFS		6
-#define REG_DRAM_TRAINING_DQS_RX_OFFS		15
-#define REG_DRAM_TRAINING_DQS_TX_OFFS		16
-#define REG_DRAM_TRAINING_CS_OFFS		20
-#define REG_DRAM_TRAINING_RETEST_OFFS		24
-#define REG_DRAM_TRAINING_DFS_FREQ_OFFS		27
-#define REG_DRAM_TRAINING_DFS_REQ_OFFS		29
-#define REG_DRAM_TRAINING_ERROR_OFFS		30
-#define REG_DRAM_TRAINING_AUTO_OFFS		31
-#define REG_DRAM_TRAINING_RETEST_PAR		0x3
-#define REG_DRAM_TRAINING_RETEST_MASK		0xf8ffffff
-#define REG_DRAM_TRAINING_CS_MASK		0xff0fffff
-#define REG_DRAM_TRAINING_PATTERNS_MASK		0xff0f0000
-
-#define REG_DRAM_TRAINING_1_ADDR		0x15b4
-#define REG_DRAM_TRAINING_1_TRNBPOINT_OFFS	16
-
-#define REG_DRAM_TRAINING_2_ADDR		0x15b8
-#define REG_DRAM_TRAINING_2_OVERRUN_OFFS	17
-#define REG_DRAM_TRAINING_2_FIFO_RST_OFFS	4
-#define REG_DRAM_TRAINING_2_RL_MODE_OFFS	3
-#define REG_DRAM_TRAINING_2_WL_MODE_OFFS	2
-#define REG_DRAM_TRAINING_2_ECC_MUX_OFFS	1
-#define REG_DRAM_TRAINING_2_SW_OVRD_OFFS	0
-
-#define REG_DRAM_TRAINING_PATTERN_BASE_ADDR	0x15bc
-#define REG_DRAM_TRAINING_PATTERN_BASE_OFFS	3
-
-#define REG_TRAINING_DEBUG_2_ADDR		0x15c4
-#define REG_TRAINING_DEBUG_2_OFFS		16
-#define REG_TRAINING_DEBUG_2_MASK		0x3
-
-#define REG_TRAINING_DEBUG_3_ADDR		0x15c8
-#define REG_TRAINING_DEBUG_3_OFFS		3
-#define REG_TRAINING_DEBUG_3_MASK		0x7
-
-#define	MR_CS_ADDR_OFFS				4
-
-#define	REG_DDR3_MR0_ADDR			0x15d0
-#define	REG_DDR3_MR0_CS_ADDR			0x1870
-#define REG_DDR3_MR0_CL_MASK			0x74
-#define	REG_DDR3_MR0_CL_OFFS			2
-#define	REG_DDR3_MR0_CL_HIGH_OFFS		3
-#define	CL_MASK					0xf
-
-#define	REG_DDR3_MR1_ADDR			0x15d4
-#define	REG_DDR3_MR1_CS_ADDR			0x1874
-#define REG_DDR3_MR1_RTT_MASK			0xfffffdbb
-#define REG_DDR3_MR1_DLL_ENA_OFFS		0
-#define REG_DDR3_MR1_RTT_DISABLED		0x0
-#define REG_DDR3_MR1_RTT_RZQ2			0x40
-#define REG_DDR3_MR1_RTT_RZQ4			0x2
-#define REG_DDR3_MR1_RTT_RZQ6			0x42
-#define REG_DDR3_MR1_RTT_RZQ8			0x202
-#define REG_DDR3_MR1_RTT_RZQ12			0x4
-/* WL-disabled, OB-enabled */
-#define REG_DDR3_MR1_OUTBUF_WL_MASK		0xffffef7f
-/* Output Buffer Disabled */
-#define REG_DDR3_MR1_OUTBUF_DIS_OFFS		12
-#define REG_DDR3_MR1_WL_ENA_OFFS		7
-#define REG_DDR3_MR1_WL_ENA			0x80	/* WL Enabled */
-#define REG_DDR3_MR1_ODT_MASK			0xfffffdbb
-
-#define	REG_DDR3_MR2_ADDR			0x15d8
-#define	REG_DDR3_MR2_CS_ADDR			0x1878
-#define	REG_DDR3_MR2_CWL_OFFS			3
-#define	REG_DDR3_MR2_CWL_MASK			0x7
-#define REG_DDR3_MR2_ODT_MASK			0xfffff9ff
-#define	REG_DDR3_MR3_ADDR			0x15dc
-#define	REG_DDR3_MR3_CS_ADDR			0x187c
-
-#define REG_DDR3_RANK_CTRL_ADDR			0x15e0
-#define REG_DDR3_RANK_CTRL_CS_ENA_MASK		0xf
-#define REG_DDR3_RANK_CTRL_MIRROR_OFFS		4
-
-#define REG_ZQC_CONF_ADDR			0x15e4
-
-#define REG_DRAM_PHY_CONFIG_ADDR		0x15ec
-#define REG_DRAM_PHY_CONFIG_MASK		0x3fffffff
-
-#define REG_ODPG_CNTRL_ADDR			0x1600
-#define REG_ODPG_CNTRL_OFFS			21
-
-#define REG_PHY_LOCK_MASK_ADDR			0x1670
-#define REG_PHY_LOCK_MASK_MASK			0xfffff000
-
-#define REG_PHY_LOCK_STATUS_ADDR		0x1674
-#define REG_PHY_LOCK_STATUS_LOCK_OFFS		9
-#define REG_PHY_LOCK_STATUS_LOCK_MASK		0xfff
-#define REG_PHY_LOCK_APLL_ADLL_STATUS_MASK	0x7ff
-
-#define REG_PHY_REGISTRY_FILE_ACCESS_ADDR	0x16a0
-#define REG_PHY_REGISTRY_FILE_ACCESS_OP_WR	0xc0000000
-#define REG_PHY_REGISTRY_FILE_ACCESS_OP_RD	0x80000000
-#define REG_PHY_REGISTRY_FILE_ACCESS_OP_DONE	0x80000000
-#define REG_PHY_BC_OFFS				27
-#define REG_PHY_CNTRL_OFFS			26
-#define REG_PHY_CS_OFFS				16
-#define REG_PHY_DQS_REF_DLY_OFFS		10
-#define REG_PHY_PHASE_OFFS			8
-#define REG_PHY_PUP_OFFS			22
-
-#define REG_TRAINING_WL_ADDR			0x16ac
-#define REG_TRAINING_WL_CS_MASK			0xfffffffc
-#define REG_TRAINING_WL_UPD_OFFS		2
-#define REG_TRAINING_WL_CS_DONE_OFFS		3
-#define REG_TRAINING_WL_RATIO_MASK		0xffffff0f
-#define REG_TRAINING_WL_1TO1			0x50
-#define REG_TRAINING_WL_2TO1			0x10
-#define REG_TRAINING_WL_DELAYEXP_MASK		0x20000000
-#define REG_TRAINING_WL_RESULTS_MASK		0x000001ff
-#define REG_TRAINING_WL_RESULTS_OFFS		20
-
-#define REG_REGISTERED_DRAM_CTRL_ADDR		0x16d0
-#define REG_REGISTERED_DRAM_CTRL_SR_FLOAT_OFFS	15
-#define REG_REGISTERED_DRAM_CTRL_PARITY_MASK	0x3f
-
-/* DLB */
-#define REG_STATIC_DRAM_DLB_CONTROL		0x1700
-#define DLB_BUS_OPTIMIZATION_WEIGHTS_REG	0x1704
-#define DLB_AGING_REGISTER			0x1708
-#define DLB_EVICTION_CONTROL_REG		0x170c
-#define DLB_EVICTION_TIMERS_REGISTER_REG	0x1710
-#define DLB_USER_COMMAND_REG			0x1714
-#define DLB_BUS_WEIGHTS_DIFF_CS			0x1770
-#define DLB_BUS_WEIGHTS_DIFF_BG			0x1774
-#define DLB_BUS_WEIGHTS_SAME_BG			0x1778
-#define DLB_BUS_WEIGHTS_RD_WR			0x177c
-#define DLB_BUS_WEIGHTS_ATTR_SYS_PRIO		0x1780
-#define DLB_MAIN_QUEUE_MAP			0x1784
-#define DLB_LINE_SPLIT				0x1788
-
-#define DLB_ENABLE				0x1
-#define DLB_WRITE_COALESING			(0x1 << 2)
-#define DLB_AXI_PREFETCH_EN			(0x1 << 3)
-#define DLB_MBUS_PREFETCH_EN			(0x1 << 4)
-#define PREFETCH_N_LN_SZ_TR			(0x1 << 6)
-#define DLB_INTERJECTION_ENABLE			(0x1 << 3)
-
-/* CPU */
-#define REG_BOOTROM_ROUTINE_ADDR		0x182d0
-#define REG_BOOTROM_ROUTINE_DRAM_INIT_OFFS	12
-
-#define REG_DRAM_INIT_CTRL_STATUS_ADDR		0x18488
-#define REG_DRAM_INIT_CTRL_TRN_CLK_OFFS		16
-#define REG_CPU_DIV_CLK_CTRL_0_NEW_RATIO	0x000200ff
-#define REG_DRAM_INIT_CTRL_STATUS_2_ADDR	0x1488
-
-#define REG_CPU_DIV_CLK_CTRL_0_ADDR		0x18700
-
-#define REG_CPU_DIV_CLK_CTRL_1_ADDR		0x18704
-#define REG_CPU_DIV_CLK_CTRL_2_ADDR		0x18708
-
-#define REG_CPU_DIV_CLK_CTRL_3_ADDR		0x1870c
-#define REG_CPU_DIV_CLK_CTRL_3_FREQ_MASK	0xffffc0ff
-#define REG_CPU_DIV_CLK_CTRL_3_FREQ_OFFS	8
-
-#define REG_CPU_DIV_CLK_CTRL_4_ADDR		0x18710
-
-#define REG_CPU_DIV_CLK_STATUS_0_ADDR		0x18718
-#define REG_CPU_DIV_CLK_ALL_STABLE_OFFS		8
-
-#define REG_CPU_PLL_CTRL_0_ADDR			0x1871c
-#define REG_CPU_PLL_STATUS_0_ADDR		0x18724
-#define REG_CORE_DIV_CLK_CTRL_ADDR		0x18740
-#define REG_CORE_DIV_CLK_STATUS_ADDR		0x18744
-#define REG_DDRPHY_APLL_CTRL_ADDR		0x18780
-
-#define REG_DDRPHY_APLL_CTRL_2_ADDR		0x18784
-#define REG_SFABRIC_CLK_CTRL_ADDR		0x20858
-#define REG_SFABRIC_CLK_CTRL_SMPL_OFFS		8
-
-/* DRAM Windows */
-#define REG_XBAR_WIN_19_CTRL_ADDR		0x200e8
-#define REG_XBAR_WIN_4_CTRL_ADDR		0x20040
-#define REG_XBAR_WIN_4_BASE_ADDR		0x20044
-#define REG_XBAR_WIN_4_REMAP_ADDR		0x20048
-#define REG_FASTPATH_WIN_0_CTRL_ADDR		0x20184
-#define REG_XBAR_WIN_7_REMAP_ADDR               0x20078
-
-/* SRAM */
-#define REG_CDI_CONFIG_ADDR			0x20220
-#define REG_SRAM_WINDOW_0_ADDR			0x20240
-#define REG_SRAM_WINDOW_0_ENA_OFFS		0
-#define REG_SRAM_WINDOW_1_ADDR			0x20244
-#define REG_SRAM_L2_ENA_ADDR			0x8500
-#define REG_SRAM_CLEAN_BY_WAY_ADDR		0x87bc
-
-/* Timers */
-#define REG_TIMERS_CTRL_ADDR			0x20300
-#define REG_TIMERS_EVENTS_ADDR			0x20304
-#define REG_TIMER0_VALUE_ADDR			0x20314
-#define REG_TIMER1_VALUE_ADDR			0x2031c
-#define REG_TIMER0_ENABLE_MASK			0x1
-
-#define MV_BOARD_REFCLK_25MHZ			25000000
-#define CNTMR_RELOAD_REG(tmr)	(REG_TIMERS_CTRL_ADDR  + 0x10 + (tmr * 8))
-#define CNTMR_VAL_REG(tmr)	(REG_TIMERS_CTRL_ADDR  + 0x14 + (tmr * 8))
-#define CNTMR_CTRL_REG(tmr)	(REG_TIMERS_CTRL_ADDR)
-#define CTCR_ARM_TIMER_EN_OFFS(timer)	(timer * 2)
-#define CTCR_ARM_TIMER_EN_MASK(timer)	(1 << CTCR_ARM_TIMER_EN_OFFS(timer))
-#define CTCR_ARM_TIMER_EN(timer)	(1 << CTCR_ARM_TIMER_EN_OFFS(timer))
-
-#define CTCR_ARM_TIMER_AUTO_OFFS(timer)	(1 + (timer * 2))
-#define CTCR_ARM_TIMER_AUTO_MASK(timer)	(1 << CTCR_ARM_TIMER_EN_OFFS(timer))
-#define CTCR_ARM_TIMER_AUTO_EN(timer)	(1 << CTCR_ARM_TIMER_AUTO_OFFS(timer))
-
-/* PMU */
-#define REG_PMU_I_F_CTRL_ADDR			0x1c090
-#define REG_PMU_DUNIT_BLK_OFFS			16
-#define REG_PMU_DUNIT_RFRS_OFFS			20
-#define REG_PMU_DUNIT_ACK_OFFS			24
-
-/* MBUS */
-#define MBUS_UNITS_PRIORITY_CONTROL_REG		(MBUS_REGS_OFFSET + 0x420)
-#define FABRIC_UNITS_PRIORITY_CONTROL_REG	(MBUS_REGS_OFFSET + 0x424)
-#define MBUS_UNITS_PREFETCH_CONTROL_REG		(MBUS_REGS_OFFSET + 0x428)
-#define FABRIC_UNITS_PREFETCH_CONTROL_REG	(MBUS_REGS_OFFSET + 0x42c)
-
-#define REG_PM_STAT_MASK_ADDR			0x2210c
-#define REG_PM_STAT_MASK_CPU0_IDLE_MASK_OFFS	16
-
-#define REG_PM_EVENT_STAT_MASK_ADDR		0x22120
-#define REG_PM_EVENT_STAT_MASK_DFS_DONE_OFFS	17
-
-#define REG_PM_CTRL_CONFIG_ADDR			0x22104
-#define REG_PM_CTRL_CONFIG_DFS_REQ_OFFS		18
-
-#define REG_FABRIC_LOCAL_IRQ_MASK_ADDR		0x218c4
-#define REG_FABRIC_LOCAL_IRQ_PMU_MASK_OFFS	18
-
-/* Controller revision info */
-#define PCI_CLASS_CODE_AND_REVISION_ID		0x008
-#define PCCRIR_REVID_OFFS			0	/* Revision ID */
-#define PCCRIR_REVID_MASK			(0xff << PCCRIR_REVID_OFFS)
-
-/* Power Management Clock Gating Control Register */
-#define POWER_MNG_CTRL_REG			0x18220
-#define PMC_PEXSTOPCLOCK_OFFS(p)	((p) < 8 ? (5 + (p)) : (18 + (p)))
-#define PMC_PEXSTOPCLOCK_MASK(p)	(1 << PMC_PEXSTOPCLOCK_OFFS(p))
-#define PMC_PEXSTOPCLOCK_EN(p)		(1 << PMC_PEXSTOPCLOCK_OFFS(p))
-#define PMC_PEXSTOPCLOCK_STOP(p)	(0 << PMC_PEXSTOPCLOCK_OFFS(p))
-
-/* TWSI */
-#define TWSI_DATA_ADDR_MASK		0x7
-#define TWSI_DATA_ADDR_OFFS		1
-
-/* General */
-#define MAX_CS				4
-
-/* Frequencies */
-#define FAB_OPT				21
-#define CLK_CPU				12
-#define CLK_VCO				(2 * CLK_CPU)
-#define CLK_DDR				12
-
-/* CPU Frequencies: */
-#define CLK_CPU_1000			0
-#define CLK_CPU_1066			1
-#define CLK_CPU_1200			2
-#define CLK_CPU_1333			3
-#define CLK_CPU_1500			4
-#define CLK_CPU_1666			5
-#define CLK_CPU_1800			6
-#define CLK_CPU_2000			7
-#define CLK_CPU_600			8
-#define CLK_CPU_667			9
-#define CLK_CPU_800			0xa
-
-/* Extra Cpu Frequencies: */
-#define CLK_CPU_1600			11
-#define CLK_CPU_2133			12
-#define CLK_CPU_2200			13
-#define CLK_CPU_2400			14
-
-#endif /* _DDR3_HWS_HW_TRAINING_DEF_H */
diff --git a/drivers/ddr/marvell/a38x/ddr3_hws_sil_training.h b/drivers/ddr/marvell/a38x/ddr3_hws_sil_training.h
deleted file mode 100644
index 544237a27620..000000000000
--- a/drivers/ddr/marvell/a38x/ddr3_hws_sil_training.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- *
- * SPDX-License-Identifier:	GPL-2.0
- */
-
-#ifndef _DDR3_HWS_SIL_TRAINING_H
-#define _DDR3_HWS_SIL_TRAINING_H
-
-#include "ddr3_training_ip.h"
-#include "ddr3_training_ip_prv_if.h"
-
-int ddr3_silicon_pre_config(void);
-int ddr3_silicon_init(void);
-int ddr3_silicon_get_ddr_target_freq(u32 *ddr_freq);
-
-#endif /* _DDR3_HWS_SIL_TRAINING_H */
diff --git a/drivers/ddr/marvell/a38x/ddr3_init.c b/drivers/ddr/marvell/a38x/ddr3_init.c
index 4790ec1d8174..482614b2aa24 100644
--- a/drivers/ddr/marvell/a38x/ddr3_init.c
+++ b/drivers/ddr/marvell/a38x/ddr3_init.c
@@ -4,239 +4,30 @@
  * SPDX-License-Identifier:	GPL-2.0
  */
 
-#include <common.h>
-#include <i2c.h>
-#include <spl.h>
-#include <asm/io.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/soc.h>
-
 #include "ddr3_init.h"
+#include "mv_ddr_common.h"
 
-#include "../../../../arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h"
-
-static struct dlb_config ddr3_dlb_config_table[] = {
-	{REG_STATIC_DRAM_DLB_CONTROL, 0x2000005c},
-	{DLB_BUS_OPTIMIZATION_WEIGHTS_REG, 0x00880000},
-	{DLB_AGING_REGISTER, 0x0f7f007f},
-	{DLB_EVICTION_CONTROL_REG, 0x0000129f},
-	{DLB_EVICTION_TIMERS_REGISTER_REG, 0x00ff0000},
-	{DLB_BUS_WEIGHTS_DIFF_CS, 0x04030802},
-	{DLB_BUS_WEIGHTS_DIFF_BG, 0x00000a02},
-	{DLB_BUS_WEIGHTS_SAME_BG, 0x09000a01},
-	{DLB_BUS_WEIGHTS_RD_WR, 0x00020005},
-	{DLB_BUS_WEIGHTS_ATTR_SYS_PRIO, 0x00060f10},
-	{DLB_MAIN_QUEUE_MAP, 0x00000543},
-	{DLB_LINE_SPLIT, 0x00000000},
-	{DLB_USER_COMMAND_REG, 0x00000000},
-	{0x0, 0x0}
-};
-
-static struct dlb_config ddr3_dlb_config_table_a0[] = {
-	{REG_STATIC_DRAM_DLB_CONTROL, 0x2000005c},
-	{DLB_BUS_OPTIMIZATION_WEIGHTS_REG, 0x00880000},
-	{DLB_AGING_REGISTER, 0x0f7f007f},
-	{DLB_EVICTION_CONTROL_REG, 0x0000129f},
-	{DLB_EVICTION_TIMERS_REGISTER_REG, 0x00ff0000},
-	{DLB_BUS_WEIGHTS_DIFF_CS, 0x04030802},
-	{DLB_BUS_WEIGHTS_DIFF_BG, 0x00000a02},
-	{DLB_BUS_WEIGHTS_SAME_BG, 0x09000a01},
-	{DLB_BUS_WEIGHTS_RD_WR, 0x00020005},
-	{DLB_BUS_WEIGHTS_ATTR_SYS_PRIO, 0x00060f10},
-	{DLB_MAIN_QUEUE_MAP, 0x00000543},
-	{DLB_LINE_SPLIT, 0x00000000},
-	{DLB_USER_COMMAND_REG, 0x00000000},
-	{0x0, 0x0}
-};
-
-#if defined(CONFIG_ARMADA_38X)
-struct dram_modes {
-	char *mode_name;
-	u8 cpu_freq;
-	u8 fab_freq;
-	u8 chip_id;
-	u8 chip_board_rev;
-	struct reg_data *regs;
-};
-
-struct dram_modes ddr_modes[] = {
-};
-#endif /* defined(CONFIG_ARMADA_38X) */
-
-/* Translates topology map definitions to real memory size in bits */
+/*
+ * Translates topology map definitions to real memory size in bits
+  * (per values in ddr3_training_ip_def.h)
+ */
 u32 mem_size[] = {
-	ADDR_SIZE_512MB, ADDR_SIZE_1GB, ADDR_SIZE_2GB, ADDR_SIZE_4GB,
+	ADDR_SIZE_512MB,
+	ADDR_SIZE_1GB,
+	ADDR_SIZE_2GB,
+	ADDR_SIZE_4GB,
 	ADDR_SIZE_8GB
 };
 
 static char *ddr_type = "DDR3";
 
 /*
- * Set 1 to use dynamic DUNIT configuration,
- * set 0 (supported for A380 and AC3) to configure DUNIT in values set by
- * ddr3_tip_init_specific_reg_config
+ * generic_init_controller controls D-unit configuration:
+ * '1' - dynamic D-unit configuration,
  */
 u8 generic_init_controller = 1;
 
-static int ddr3_hws_tune_training_params(u8 dev_num);
-
-/* device revision */
-#define DEV_VERSION_ID_REG		0x1823c
-#define REVISON_ID_OFFS			8
-#define REVISON_ID_MASK			0xf00
-
-/* A38x revisions */
-#define MV_88F68XX_Z1_ID		0x0
-#define MV_88F68XX_A0_ID		0x4
-/* A39x revisions */
-#define MV_88F69XX_Z1_ID		0x2
-
-/*
- * sys_env_dlb_config_ptr_get
- *
- * DESCRIPTION: defines pointer to to DLB COnfiguration table
- *
- * INPUT: none
- *
- * OUTPUT: pointer to DLB COnfiguration table
- *
- * RETURN:
- *       returns pointer to DLB COnfiguration table
- */
-struct dlb_config *sys_env_dlb_config_ptr_get(void)
-{
-#ifdef CONFIG_ARMADA_39X
-	return &ddr3_dlb_config_table_a0[0];
-#else
-	if (sys_env_device_rev_get() == MV_88F68XX_A0_ID)
-		return &ddr3_dlb_config_table_a0[0];
-	else
-		return &ddr3_dlb_config_table[0];
-#endif
-}
-
-/*
- * sys_env_get_cs_ena_from_reg
- *
- * DESCRIPTION: Get bit mask of enabled CS
- *
- * INPUT: None
- *
- * OUTPUT: None
- *
- * RETURN:
- *       Bit mask of enabled CS, 1 if only CS0 enabled,
- *       3 if both CS0 and CS1 enabled
- */
-u32 sys_env_get_cs_ena_from_reg(void)
-{
-	return reg_read(REG_DDR3_RANK_CTRL_ADDR) &
-		REG_DDR3_RANK_CTRL_CS_ENA_MASK;
-}
-
-static void ddr3_restore_and_set_final_windows(u32 *win)
-{
-	u32 win_ctrl_reg, num_of_win_regs;
-	u32 cs_ena = sys_env_get_cs_ena_from_reg();
-	u32 ui;
-
-	win_ctrl_reg = REG_XBAR_WIN_4_CTRL_ADDR;
-	num_of_win_regs = 16;
-
-	/* Return XBAR windows 4-7 or 16-19 init configuration */
-	for (ui = 0; ui < num_of_win_regs; ui++)
-		reg_write((win_ctrl_reg + 0x4 * ui), win[ui]);
-
-	printf("%s Training Sequence - Switching XBAR Window to FastPath Window\n",
-	       ddr_type);
-
-#if defined DYNAMIC_CS_SIZE_CONFIG
-	if (ddr3_fast_path_dynamic_cs_size_config(cs_ena) != MV_OK)
-		printf("ddr3_fast_path_dynamic_cs_size_config FAILED\n");
-#else
-	u32 reg, cs;
-	reg = 0x1fffffe1;
-	for (cs = 0; cs < MAX_CS; cs++) {
-		if (cs_ena & (1 << cs)) {
-			reg |= (cs << 2);
-			break;
-		}
-	}
-	/* Open fast path Window to - 0.5G */
-	reg_write(REG_FASTPATH_WIN_0_CTRL_ADDR, reg);
-#endif
-}
-
-static int ddr3_save_and_set_training_windows(u32 *win)
-{
-	u32 cs_ena;
-	u32 reg, tmp_count, cs, ui;
-	u32 win_ctrl_reg, win_base_reg, win_remap_reg;
-	u32 num_of_win_regs, win_jump_index;
-	win_ctrl_reg = REG_XBAR_WIN_4_CTRL_ADDR;
-	win_base_reg = REG_XBAR_WIN_4_BASE_ADDR;
-	win_remap_reg = REG_XBAR_WIN_4_REMAP_ADDR;
-	win_jump_index = 0x10;
-	num_of_win_regs = 16;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
-
-#ifdef DISABLE_L2_FILTERING_DURING_DDR_TRAINING
-	/*
-	 * Disable L2 filtering during DDR training
-	 * (when Cross Bar window is open)
-	 */
-	reg_write(ADDRESS_FILTERING_END_REGISTER, 0);
-#endif
-
-	cs_ena = tm->interface_params[0].as_bus_params[0].cs_bitmask;
-
-	/* Close XBAR Window 19 - Not needed */
-	/* {0x000200e8}  -   Open Mbus Window - 2G */
-	reg_write(REG_XBAR_WIN_19_CTRL_ADDR, 0);
-
-	/* Save XBAR Windows 4-19 init configurations */
-	for (ui = 0; ui < num_of_win_regs; ui++)
-		win[ui] = reg_read(win_ctrl_reg + 0x4 * ui);
-
-	/* Open XBAR Windows 4-7 or 16-19 for other CS */
-	reg = 0;
-	tmp_count = 0;
-	for (cs = 0; cs < MAX_CS; cs++) {
-		if (cs_ena & (1 << cs)) {
-			switch (cs) {
-			case 0:
-				reg = 0x0e00;
-				break;
-			case 1:
-				reg = 0x0d00;
-				break;
-			case 2:
-				reg = 0x0b00;
-				break;
-			case 3:
-				reg = 0x0700;
-				break;
-			}
-			reg |= (1 << 0);
-			reg |= (SDRAM_CS_SIZE & 0xffff0000);
-
-			reg_write(win_ctrl_reg + win_jump_index * tmp_count,
-				  reg);
-			reg = (((SDRAM_CS_SIZE + 1) * (tmp_count)) &
-			       0xffff0000);
-			reg_write(win_base_reg + win_jump_index * tmp_count,
-				  reg);
-
-			if (win_remap_reg <= REG_XBAR_WIN_7_REMAP_ADDR)
-				reg_write(win_remap_reg +
-					  win_jump_index * tmp_count, 0);
-
-			tmp_count++;
-		}
-	}
-
-	return MV_OK;
-}
+static int mv_ddr_training_params_set(u8 dev_num);
 
 /*
  * Name:     ddr3_init - Main DDR3 Init function
@@ -247,464 +38,182 @@ static int ddr3_save_and_set_training_windows(u32 *win)
  */
 int ddr3_init(void)
 {
-	u32 reg = 0;
-	u32 soc_num;
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+	u32 octets_per_if_num;
 	int status;
-	u32 win[16];
-
-	/* SoC/Board special Initializtions */
-	/* Get version from internal library */
-	ddr3_print_version();
-
-	/*Add sub_version string */
-	DEBUG_INIT_C("", SUB_VERSION, 1);
-
-	/* Switching CPU to MRVL ID */
-	soc_num = (reg_read(REG_SAMPLE_RESET_HIGH_ADDR) & SAR1_CPU_CORE_MASK) >>
-		SAR1_CPU_CORE_OFFSET;
-	switch (soc_num) {
-	case 0x3:
-	case 0x1:
-		reg_bit_set(CPU_CONFIGURATION_REG(1), CPU_MRVL_ID_OFFSET);
-	case 0x0:
-		reg_bit_set(CPU_CONFIGURATION_REG(0), CPU_MRVL_ID_OFFSET);
-	default:
-		break;
-	}
+	int is_manual_cal_done;
 
-	/*
-	 * Set DRAM Reset Mask in case detected GPIO indication of wakeup from
-	 * suspend i.e the DRAM values will not be overwritten / reset when
-	 * waking from suspend
-	 */
-	if (sys_env_suspend_wakeup_check() ==
-	    SUSPEND_WAKEUP_ENABLED_GPIO_DETECTED) {
-		reg_bit_set(REG_SDRAM_INIT_CTRL_ADDR,
-			    1 << REG_SDRAM_INIT_RESET_MASK_OFFS);
-	}
+	/* Print mv_ddr version */
+	mv_ddr_ver_print();
 
-	/*
-	 * Stage 0 - Set board configuration
-	 */
+	mv_ddr_pre_training_fixup();
 
-	/* Check if DRAM is already initialized  */
-	if (reg_read(REG_BOOTROM_ROUTINE_ADDR) &
-	    (1 << REG_BOOTROM_ROUTINE_DRAM_INIT_OFFS)) {
-		printf("%s Training Sequence - 2nd boot - Skip\n", ddr_type);
-		return MV_OK;
-	}
+	/* SoC/Board special initializations */
+	mv_ddr_pre_training_soc_config(ddr_type);
 
-	/*
-	 * Stage 1 - Dunit Setup
-	 */
-
-	/* Fix read ready phases for all SOC in reg 0x15c8 */
-	reg = reg_read(REG_TRAINING_DEBUG_3_ADDR);
-	reg &= ~(REG_TRAINING_DEBUG_3_MASK);
-	reg |= 0x4;		/* Phase 0 */
-	reg &= ~(REG_TRAINING_DEBUG_3_MASK << REG_TRAINING_DEBUG_3_OFFS);
-	reg |= (0x4 << (1 * REG_TRAINING_DEBUG_3_OFFS));	/* Phase 1 */
-	reg &= ~(REG_TRAINING_DEBUG_3_MASK << (3 * REG_TRAINING_DEBUG_3_OFFS));
-	reg |= (0x6 << (3 * REG_TRAINING_DEBUG_3_OFFS));	/* Phase 3 */
-	reg &= ~(REG_TRAINING_DEBUG_3_MASK << (4 * REG_TRAINING_DEBUG_3_OFFS));
-	reg |= (0x6 << (4 * REG_TRAINING_DEBUG_3_OFFS));
-	reg &= ~(REG_TRAINING_DEBUG_3_MASK << (5 * REG_TRAINING_DEBUG_3_OFFS));
-	reg |= (0x6 << (5 * REG_TRAINING_DEBUG_3_OFFS));
-	reg_write(REG_TRAINING_DEBUG_3_ADDR, reg);
-
-	/*
-	 * Axi_bresp_mode[8] = Compliant,
-	 * Axi_addr_decode_cntrl[11] = Internal,
-	 * Axi_data_bus_width[0] = 128bit
-	 * */
-	/* 0x14a8 - AXI Control Register */
-	reg_write(REG_DRAM_AXI_CTRL_ADDR, 0);
-
-	/*
-	 * Stage 2 - Training Values Setup
-	 */
-	/* Set X-BAR windows for the training sequence */
-	ddr3_save_and_set_training_windows(win);
-
-
-	/* Tune training algo paramteres */
-	status = ddr3_hws_tune_training_params(0);
-	if (MV_OK != status)
-		return status;
+	/* Set log level for training library */
+	mv_ddr_user_log_level_set(DEBUG_BLOCK_ALL);
 
-	/* Set log level for training lib */
-	ddr3_hws_set_log_level(DEBUG_BLOCK_ALL, DEBUG_LEVEL_ERROR);
+	mv_ddr_early_init();
 
-	/* Start New Training IP */
-	status = ddr3_hws_hw_training();
-	if (MV_OK != status) {
-		printf("%s Training Sequence - FAILED\n", ddr_type);
-		return status;
+	if (mv_ddr_topology_map_update() == NULL) {
+		printf("mv_ddr: failed to update topology\n");
+		return MV_FAIL;
 	}
 
-	/*
-	 * Stage 3 - Finish
-	 */
-	/* Restore and set windows */
-	ddr3_restore_and_set_final_windows(win);
-
-	/* Update DRAM init indication in bootROM register */
-	reg = reg_read(REG_BOOTROM_ROUTINE_ADDR);
-	reg_write(REG_BOOTROM_ROUTINE_ADDR,
-		  reg | (1 << REG_BOOTROM_ROUTINE_DRAM_INIT_OFFS));
-
-	/* DLB config */
-	ddr3_new_tip_dlb_config();
-
-#if defined(ECC_SUPPORT)
-	if (ddr3_if_ecc_enabled())
-		ddr3_new_tip_ecc_scrub();
-#endif
-
-	printf("%s Training Sequence - Ended Successfully\n", ddr_type);
-
-	return MV_OK;
-}
+	if (mv_ddr_early_init2() != MV_OK)
+		return MV_FAIL;
 
-/*
- * Name:     ddr3_get_cpu_freq
- * Desc:     read S at R and return CPU frequency
- * Args:
- * Notes:
- * Returns:  required value
- */
-u32 ddr3_get_cpu_freq(void)
-{
-	return ddr3_tip_get_init_freq();
-}
+	/* Set training algorithm's parameters */
+	status = mv_ddr_training_params_set(0);
+	if (MV_OK != status)
+		return status;
 
-/*
- * Name:     ddr3_get_fab_opt
- * Desc:     read S@R and return CPU frequency
- * Args:
- * Notes:
- * Returns:  required value
- */
-u32 ddr3_get_fab_opt(void)
-{
-	return 0;		/* No fabric */
-}
 
-/*
- * Name:     ddr3_get_static_m_cValue - Init Memory controller with
- *           static parameters
- * Desc:     Use this routine to init the controller without the HW training
- *           procedure.
- *           User must provide compatible header file with registers data.
- * Args:     None.
- * Notes:
- * Returns:  None.
- */
-u32 ddr3_get_static_mc_value(u32 reg_addr, u32 offset1, u32 mask1,
-			     u32 offset2, u32 mask2)
-{
-	u32 reg, temp;
+	mv_ddr_mc_config();
 
-	reg = reg_read(reg_addr);
+	is_manual_cal_done = mv_ddr_manual_cal_do();
 
-	temp = (reg >> offset1) & mask1;
-	if (mask2)
-		temp |= (reg >> offset2) & mask2;
+	mv_ddr_mc_init();
 
-	return temp;
-}
+	if (!is_manual_cal_done) {
+	}
 
-/*
- * Name:     ddr3_get_static_ddr_mode - Init Memory controller with
- *           static parameters
- * Desc:     Use this routine to init the controller without the HW training
- *           procedure.
- *           User must provide compatible header file with registers data.
- * Args:     None.
- * Notes:
- * Returns:  None.
- */
-u32 ddr3_get_static_ddr_mode(void)
-{
-	u32 chip_board_rev, i;
-	u32 size;
-
-	/* Valid only for A380 only, MSYS using dynamic controller config */
-#ifdef CONFIG_CUSTOMER_BOARD_SUPPORT
-	/*
-	 * Customer boards select DDR mode according to
-	 * board ID & Sample at Reset
-	 */
-	chip_board_rev = mv_board_id_get();
-#else
-	/* Marvell boards select DDR mode according to Sample at Reset only */
-	chip_board_rev = MARVELL_BOARD;
-#endif
 
-	size = ARRAY_SIZE(ddr_modes);
-	for (i = 0; i < size; i++) {
-		if ((ddr3_get_cpu_freq() == ddr_modes[i].cpu_freq) &&
-		    (ddr3_get_fab_opt() == ddr_modes[i].fab_freq) &&
-		    (chip_board_rev == ddr_modes[i].chip_board_rev))
-			return i;
+	status = ddr3_silicon_post_init();
+	if (MV_OK != status) {
+		printf("DDR3 Post Init - FAILED 0x%x\n", status);
+		return status;
 	}
 
-	DEBUG_INIT_S("\n*** Error: ddr3_get_static_ddr_mode: No match for requested DDR mode. ***\n\n");
-
-	return 0;
-}
+	/* PHY initialization (Training) */
+	status = hws_ddr3_tip_run_alg(0, ALGO_TYPE_DYNAMIC);
+	if (MV_OK != status) {
+		printf("%s Training Sequence - FAILED\n", ddr_type);
+		return status;
+	}
 
-/******************************************************************************
- * Name:     ddr3_get_cs_num_from_reg
- * Desc:
- * Args:
- * Notes:
- * Returns:
- */
-u32 ddr3_get_cs_num_from_reg(void)
-{
-	u32 cs_ena = sys_env_get_cs_ena_from_reg();
-	u32 cs_count = 0;
-	u32 cs;
+#if defined(CONFIG_PHY_STATIC_PRINT)
+	mv_ddr_phy_static_print();
+#endif
 
-	for (cs = 0; cs < MAX_CS; cs++) {
-		if (cs_ena & (1 << cs))
-			cs_count++;
-	}
+	/* Post MC/PHY initializations */
+	mv_ddr_post_training_soc_config(ddr_type);
 
-	return cs_count;
-}
+	mv_ddr_post_training_fixup();
 
-void get_target_freq(u32 freq_mode, u32 *ddr_freq, u32 *hclk_ps)
-{
-	u32 tmp, hclk = 200;
-
-	switch (freq_mode) {
-	case 4:
-		tmp = 1;	/* DDR_400; */
-		hclk = 200;
-		break;
-	case 0x8:
-		tmp = 1;	/* DDR_666; */
-		hclk = 333;
-		break;
-	case 0xc:
-		tmp = 1;	/* DDR_800; */
-		hclk = 400;
-		break;
-	default:
-		*ddr_freq = 0;
-		*hclk_ps = 0;
-		break;
+	octets_per_if_num = ddr3_tip_dev_attr_get(0, MV_ATTR_OCTET_PER_INTERFACE);
+	if (ddr3_if_ecc_enabled()) {
+		if (MV_DDR_IS_64BIT_DRAM_MODE(tm->bus_act_mask) ||
+		    MV_DDR_IS_32BIT_IN_64BIT_DRAM_MODE(tm->bus_act_mask, octets_per_if_num))
+			mv_ddr_mem_scrubbing();
+		else
+			ddr3_new_tip_ecc_scrub();
 	}
 
-	*ddr_freq = tmp;		/* DDR freq define */
-	*hclk_ps = 1000000 / hclk;	/* values are 1/HCLK in ps */
+	printf("mv_ddr: completed successfully\n");
 
-	return;
+	return MV_OK;
 }
 
-void ddr3_new_tip_dlb_config(void)
+uint64_t mv_ddr_get_memory_size_per_cs_in_bits(void)
 {
-	u32 reg, i = 0;
-	struct dlb_config *config_table_ptr = sys_env_dlb_config_ptr_get();
-
-	/* Write the configuration */
-	while (config_table_ptr[i].reg_addr != 0) {
-		reg_write(config_table_ptr[i].reg_addr,
-			  config_table_ptr[i].reg_data);
-		i++;
-	}
+	uint64_t memory_size_per_cs;
 
-	/* Enable DLB */
-	reg = reg_read(REG_STATIC_DRAM_DLB_CONTROL);
-	reg |= DLB_ENABLE | DLB_WRITE_COALESING | DLB_AXI_PREFETCH_EN |
-		DLB_MBUS_PREFETCH_EN | PREFETCH_N_LN_SZ_TR;
-	reg_write(REG_STATIC_DRAM_DLB_CONTROL, reg);
-}
+	u32 bus_cnt, num_of_active_bus = 0;
+	u32 num_of_sub_phys_per_ddr_unit = 0;
 
-int ddr3_fast_path_dynamic_cs_size_config(u32 cs_ena)
-{
-	u32 reg, cs;
-	u32 mem_total_size = 0;
-	u32 cs_mem_size = 0;
-	u32 mem_total_size_c, cs_mem_size_c;
-
-#ifdef DEVICE_MAX_DRAM_ADDRESS_SIZE
-	u32 physical_mem_size;
-	u32 max_mem_size = DEVICE_MAX_DRAM_ADDRESS_SIZE;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
-#endif
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
-	/* Open fast path windows */
-	for (cs = 0; cs < MAX_CS; cs++) {
-		if (cs_ena & (1 << cs)) {
-			/* get CS size */
-			if (ddr3_calc_mem_cs_size(cs, &cs_mem_size) != MV_OK)
-				return MV_FAIL;
-
-#ifdef DEVICE_MAX_DRAM_ADDRESS_SIZE
-			/*
-			 * if number of address pins doesn't allow to use max
-			 * mem size that is defined in topology
-			 * mem size is defined by DEVICE_MAX_DRAM_ADDRESS_SIZE
-			 */
-			physical_mem_size = mem_size
-				[tm->interface_params[0].memory_size];
-
-			if (ddr3_get_device_width(cs) == 16) {
-				/*
-				 * 16bit mem device can be twice more - no need
-				 * in less significant pin
-				 */
-				max_mem_size = DEVICE_MAX_DRAM_ADDRESS_SIZE * 2;
-			}
-
-			if (physical_mem_size > max_mem_size) {
-				cs_mem_size = max_mem_size *
-					(ddr3_get_bus_width() /
-					 ddr3_get_device_width(cs));
-				printf("Updated Physical Mem size is from 0x%x to %x\n",
-				       physical_mem_size,
-				       DEVICE_MAX_DRAM_ADDRESS_SIZE);
-			}
-#endif
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(DEV_NUM_0, MV_ATTR_OCTET_PER_INTERFACE);
 
-			/* set fast path window control for the cs */
-			reg = 0xffffe1;
-			reg |= (cs << 2);
-			reg |= (cs_mem_size - 1) & 0xffff0000;
-			/*Open fast path Window */
-			reg_write(REG_FASTPATH_WIN_CTRL_ADDR(cs), reg);
-
-			/* Set fast path window base address for the cs */
-			reg = ((cs_mem_size) * cs) & 0xffff0000;
-			/* Set base address */
-			reg_write(REG_FASTPATH_WIN_BASE_ADDR(cs), reg);
-
-			/*
-			 * Since memory size may be bigger than 4G the summ may
-			 * be more than 32 bit word,
-			 * so to estimate the result divide mem_total_size and
-			 * cs_mem_size by 0x10000 (it is equal to >> 16)
-			 */
-			mem_total_size_c = mem_total_size >> 16;
-			cs_mem_size_c = cs_mem_size >> 16;
-			/* if the sum less than 2 G - calculate the value */
-			if (mem_total_size_c + cs_mem_size_c < 0x10000)
-				mem_total_size += cs_mem_size;
-			else	/* put max possible size */
-				mem_total_size = L2_FILTER_FOR_MAX_MEMORY_SIZE;
-		}
+	/* count the number of active bus */
+	for (bus_cnt = 0; bus_cnt < octets_per_if_num - 1/* ignore ecc octet */; bus_cnt++) {
+		VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_cnt);
+		num_of_active_bus++;
 	}
 
-	/* Set L2 filtering to Max Memory size */
-	reg_write(ADDRESS_FILTERING_END_REGISTER, mem_total_size);
+	/* calculate number of sub-phys per ddr unit */
+	if (tm->interface_params[0].bus_width/* supports only single interface */ == MV_DDR_DEV_WIDTH_16BIT)
+		num_of_sub_phys_per_ddr_unit = TWO_SUB_PHYS;
+	if (tm->interface_params[0].bus_width/* supports only single interface */ == MV_DDR_DEV_WIDTH_8BIT)
+		num_of_sub_phys_per_ddr_unit = SINGLE_SUB_PHY;
 
-	return MV_OK;
-}
-
-u32 ddr3_get_bus_width(void)
-{
-	u32 bus_width;
+	/* calculate dram size per cs */
+	memory_size_per_cs = (uint64_t)mem_size[tm->interface_params[0].memory_size] * (uint64_t)num_of_active_bus
+		/ (uint64_t)num_of_sub_phys_per_ddr_unit * (uint64_t)MV_DDR_NUM_BITS_IN_BYTE;
 
-	bus_width = (reg_read(REG_SDRAM_CONFIG_ADDR) & 0x8000) >>
-		REG_SDRAM_CONFIG_WIDTH_OFFS;
-
-	return (bus_width == 0) ? 16 : 32;
+	return memory_size_per_cs;
 }
 
-u32 ddr3_get_device_width(u32 cs)
+uint64_t mv_ddr_get_total_memory_size_in_bits(void)
 {
-	u32 device_width;
+	uint64_t total_memory_size = 0;
+	uint64_t memory_size_per_cs = 0;
 
-	device_width = (reg_read(REG_SDRAM_ADDRESS_CTRL_ADDR) &
-			(0x3 << (REG_SDRAM_ADDRESS_CTRL_STRUCT_OFFS * cs))) >>
-		(REG_SDRAM_ADDRESS_CTRL_STRUCT_OFFS * cs);
+	/* get the number of cs */
+	u32 max_cs = ddr3_tip_max_cs_get(DEV_NUM_0);
 
-	return (device_width == 0) ? 8 : 16;
-}
+	memory_size_per_cs = mv_ddr_get_memory_size_per_cs_in_bits();
+	total_memory_size = (uint64_t)max_cs * memory_size_per_cs;
 
-static int ddr3_get_device_size(u32 cs)
-{
-	u32 device_size_low, device_size_high, device_size;
-	u32 data, cs_low_offset, cs_high_offset;
-
-	cs_low_offset = REG_SDRAM_ADDRESS_SIZE_OFFS + cs * 4;
-	cs_high_offset = REG_SDRAM_ADDRESS_SIZE_OFFS +
-		REG_SDRAM_ADDRESS_SIZE_HIGH_OFFS + cs;
-
-	data = reg_read(REG_SDRAM_ADDRESS_CTRL_ADDR);
-	device_size_low = (data >> cs_low_offset) & 0x3;
-	device_size_high = (data >> cs_high_offset) & 0x1;
-
-	device_size = device_size_low | (device_size_high << 2);
-
-	switch (device_size) {
-	case 0:
-		return 2048;
-	case 2:
-		return 512;
-	case 3:
-		return 1024;
-	case 4:
-		return 4096;
-	case 5:
-		return 8192;
-	case 1:
-	default:
-		DEBUG_INIT_C("Error: Wrong device size of Cs: ", cs, 1);
-		/*
-		 * Small value will give wrong emem size in
-		 * ddr3_calc_mem_cs_size
-		 */
-		return 0;
-	}
+	return total_memory_size;
 }
 
-int ddr3_calc_mem_cs_size(u32 cs, u32 *cs_size)
+int ddr3_if_ecc_enabled(void)
 {
-	int cs_mem_size;
-
-	/* Calculate in GiB */
-	cs_mem_size = ((ddr3_get_bus_width() / ddr3_get_device_width(cs)) *
-		       ddr3_get_device_size(cs)) / 8;
-
-	/*
-	 * Multiple controller bus width, 2x for 64 bit
-	 * (SoC controller may be 32 or 64 bit,
-	 * so bit 15 in 0x1400, that means if whole bus used or only half,
-	 * have a differnt meaning
-	 */
-	cs_mem_size *= DDR_CONTROLLER_BUS_WIDTH_MULTIPLIER;
-
-	if (!cs_mem_size || (cs_mem_size == 64) || (cs_mem_size == 4096)) {
-		DEBUG_INIT_C("Error: Wrong Memory size of Cs: ", cs, 1);
-		return MV_BAD_VALUE;
-	}
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
-	*cs_size = cs_mem_size << 20;
-	return MV_OK;
+	if (DDR3_IS_ECC_PUP4_MODE(tm->bus_act_mask) ||
+	    DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask) ||
+	    DDR3_IS_ECC_PUP8_MODE(tm->bus_act_mask))
+		return 1;
+	else
+		return 0;
 }
 
 /*
- * Name:     ddr3_hws_tune_training_params
+ * Name:	mv_ddr_training_params_set
  * Desc:
  * Args:
- * Notes: Tune internal training params
+ * Notes:	sets internal training params
  * Returns:
  */
-static int ddr3_hws_tune_training_params(u8 dev_num)
+static int mv_ddr_training_params_set(u8 dev_num)
 {
 	struct tune_train_params params;
 	int status;
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+	u32 if_id;
+	u32 cs_num;
+
+	CHECK_STATUS(ddr3_tip_get_first_active_if
+		     (dev_num, tm->if_act_mask,
+		      &if_id));
+
+	CHECK_STATUS(calc_cs_num(dev_num, if_id, &cs_num));
 
 	/* NOTE: do not remove any field initilization */
 	params.ck_delay = TUNE_TRAINING_PARAMS_CK_DELAY;
-	params.ck_delay_16 = TUNE_TRAINING_PARAMS_CK_DELAY_16;
-	params.p_finger = TUNE_TRAINING_PARAMS_PFINGER;
-	params.n_finger = TUNE_TRAINING_PARAMS_NFINGER;
 	params.phy_reg3_val = TUNE_TRAINING_PARAMS_PHYREG3VAL;
+	params.g_zpri_data = TUNE_TRAINING_PARAMS_PRI_DATA;
+	params.g_znri_data = TUNE_TRAINING_PARAMS_NRI_DATA;
+	params.g_zpri_ctrl = TUNE_TRAINING_PARAMS_PRI_CTRL;
+	params.g_znri_ctrl = TUNE_TRAINING_PARAMS_NRI_CTRL;
+	params.g_znodt_data = TUNE_TRAINING_PARAMS_N_ODT_DATA;
+	params.g_zpodt_ctrl = TUNE_TRAINING_PARAMS_P_ODT_CTRL;
+	params.g_znodt_ctrl = TUNE_TRAINING_PARAMS_N_ODT_CTRL;
+
+	params.g_zpodt_data = TUNE_TRAINING_PARAMS_P_ODT_DATA;
+	params.g_dic = TUNE_TRAINING_PARAMS_DIC;
+	params.g_rtt_nom = TUNE_TRAINING_PARAMS_RTT_NOM;
+	if (cs_num == 1) {
+		params.g_rtt_wr = TUNE_TRAINING_PARAMS_RTT_WR_1CS;
+		params.g_odt_config = TUNE_TRAINING_PARAMS_ODT_CONFIG_1CS;
+	} else {
+		params.g_rtt_wr = TUNE_TRAINING_PARAMS_RTT_WR_2CS;
+		params.g_odt_config = TUNE_TRAINING_PARAMS_ODT_CONFIG_2CS;
+	}
 
 	status = ddr3_tip_tune_training_params(dev_num, &params);
 	if (MV_OK != status) {
diff --git a/drivers/ddr/marvell/a38x/ddr3_init.h b/drivers/ddr/marvell/a38x/ddr3_init.h
index cbf072cdef6f..70f5657f8893 100644
--- a/drivers/ddr/marvell/a38x/ddr3_init.h
+++ b/drivers/ddr/marvell/a38x/ddr3_init.h
@@ -7,12 +7,12 @@
 #ifndef _DDR3_INIT_H
 #define _DDR3_INIT_H
 
-#if defined(CONFIG_ARMADA_38X)
-#include "ddr3_a38x.h"
-#include "ddr3_a38x_topology.h"
+#include "ddr_ml_wrapper.h"
+#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X)
+#include "mv_ddr_plat.h"
 #endif
-#include "ddr3_hws_hw_training.h"
-#include "ddr3_hws_sil_training.h"
+
+#include "seq_exec.h"
 #include "ddr3_logging_def.h"
 #include "ddr3_training_hw_algo.h"
 #include "ddr3_training_ip.h"
@@ -21,119 +21,9 @@
 #include "ddr3_training_ip_flow.h"
 #include "ddr3_training_ip_pbs.h"
 #include "ddr3_training_ip_prv_if.h"
-#include "ddr3_training_ip_static.h"
 #include "ddr3_training_leveling.h"
 #include "xor.h"
 
-/*
- * MV_DEBUG_INIT need to be defines, otherwise the output of the
- * DDR2 training code is not complete and misleading
- */
-#define MV_DEBUG_INIT
-
-#ifdef MV_DEBUG_INIT
-#define DEBUG_INIT_S(s)			puts(s)
-#define DEBUG_INIT_D(d, l)		printf("%x", d)
-#define DEBUG_INIT_D_10(d, l)		printf("%d", d)
-#else
-#define DEBUG_INIT_S(s)
-#define DEBUG_INIT_D(d, l)
-#define DEBUG_INIT_D_10(d, l)
-#endif
-
-#ifdef MV_DEBUG_INIT_FULL
-#define DEBUG_INIT_FULL_S(s)		puts(s)
-#define DEBUG_INIT_FULL_D(d, l)		printf("%x", d)
-#define DEBUG_INIT_FULL_D_10(d, l)	printf("%d", d)
-#define DEBUG_WR_REG(reg, val) \
-	{ DEBUG_INIT_S("Write Reg: 0x"); DEBUG_INIT_D((reg), 8); \
-	  DEBUG_INIT_S("= "); DEBUG_INIT_D((val), 8); DEBUG_INIT_S("\n"); }
-#define DEBUG_RD_REG(reg, val) \
-	{ DEBUG_INIT_S("Read  Reg: 0x"); DEBUG_INIT_D((reg), 8); \
-	  DEBUG_INIT_S("= "); DEBUG_INIT_D((val), 8); DEBUG_INIT_S("\n"); }
-#else
-#define DEBUG_INIT_FULL_S(s)
-#define DEBUG_INIT_FULL_D(d, l)
-#define DEBUG_INIT_FULL_D_10(d, l)
-#define DEBUG_WR_REG(reg, val)
-#define DEBUG_RD_REG(reg, val)
-#endif
-
-#define DEBUG_INIT_FULL_C(s, d, l)			\
-	{ DEBUG_INIT_FULL_S(s);				\
-	  DEBUG_INIT_FULL_D(d, l);			\
-	  DEBUG_INIT_FULL_S("\n"); }
-#define DEBUG_INIT_C(s, d, l) \
-	{ DEBUG_INIT_S(s); DEBUG_INIT_D(d, l); DEBUG_INIT_S("\n"); }
-
-/*
- * Debug (Enable/Disable modules) and Error report
- */
-
-#ifdef BASIC_DEBUG
-#define MV_DEBUG_WL
-#define MV_DEBUG_RL
-#define MV_DEBUG_DQS_RESULTS
-#endif
-
-#ifdef FULL_DEBUG
-#define MV_DEBUG_WL
-#define MV_DEBUG_RL
-#define MV_DEBUG_DQS
-
-#define MV_DEBUG_PBS
-#define MV_DEBUG_DFS
-#define MV_DEBUG_MAIN_FULL
-#define MV_DEBUG_DFS_FULL
-#define MV_DEBUG_DQS_FULL
-#define MV_DEBUG_RL_FULL
-#define MV_DEBUG_WL_FULL
-#endif
-
-#if defined(CONFIG_ARMADA_38X)
-#include "ddr3_a38x.h"
-#include "ddr3_a38x_topology.h"
-#endif
-
-/* The following is a list of Marvell status */
-#define MV_ERROR	(-1)
-#define MV_OK		(0x00)	/* Operation succeeded                   */
-#define MV_FAIL		(0x01)	/* Operation failed                      */
-#define MV_BAD_VALUE	(0x02)	/* Illegal value (general)               */
-#define MV_OUT_OF_RANGE	(0x03)	/* The value is out of range             */
-#define MV_BAD_PARAM	(0x04)	/* Illegal parameter in function called  */
-#define MV_BAD_PTR	(0x05)	/* Illegal pointer value                 */
-#define MV_BAD_SIZE	(0x06)	/* Illegal size                          */
-#define MV_BAD_STATE	(0x07)	/* Illegal state of state machine        */
-#define MV_SET_ERROR	(0x08)	/* Set operation failed                  */
-#define MV_GET_ERROR	(0x09)	/* Get operation failed                  */
-#define MV_CREATE_ERROR	(0x0a)	/* Fail while creating an item           */
-#define MV_NOT_FOUND	(0x0b)	/* Item not found                        */
-#define MV_NO_MORE	(0x0c)	/* No more items found                   */
-#define MV_NO_SUCH	(0x0d)	/* No such item                          */
-#define MV_TIMEOUT	(0x0e)	/* Time Out                              */
-#define MV_NO_CHANGE	(0x0f)	/* Parameter(s) is already in this value */
-#define MV_NOT_SUPPORTED (0x10)	/* This request is not support           */
-#define MV_NOT_IMPLEMENTED (0x11) /* Request supported but not implemented*/
-#define MV_NOT_INITIALIZED (0x12) /* The item is not initialized          */
-#define MV_NO_RESOURCE	(0x13)	/* Resource not available (memory ...)   */
-#define MV_FULL		(0x14)	/* Item is full (Queue or table etc...)  */
-#define MV_EMPTY	(0x15)	/* Item is empty (Queue or table etc...) */
-#define MV_INIT_ERROR	(0x16)	/* Error occurred while INIT process      */
-#define MV_HW_ERROR	(0x17)	/* Hardware error                        */
-#define MV_TX_ERROR	(0x18)	/* Transmit operation not succeeded      */
-#define MV_RX_ERROR	(0x19)	/* Recieve operation not succeeded       */
-#define MV_NOT_READY	(0x1a)	/* The other side is not ready yet       */
-#define MV_ALREADY_EXIST (0x1b)	/* Tried to create existing item         */
-#define MV_OUT_OF_CPU_MEM   (0x1c) /* Cpu memory allocation failed.      */
-#define MV_NOT_STARTED	(0x1d)	/* Not started yet                       */
-#define MV_BUSY		(0x1e)	/* Item is busy.                         */
-#define MV_TERMINATE	(0x1f)	/* Item terminates it's work.            */
-#define MV_NOT_ALIGNED	(0x20)	/* Wrong alignment                       */
-#define MV_NOT_ALLOWED	(0x21)	/* Operation NOT allowed                 */
-#define MV_WRITE_PROTECT (0x22)	/* Write protected                       */
-#define MV_INVALID	(int)(-1)
-
 /* For checking function return values */
 #define CHECK_STATUS(orig_func)		\
 	{				\
@@ -143,6 +33,14 @@
 			return status;	\
 	}
 
+#define GET_MAX_VALUE(x, y)			\
+	((x) > (y)) ? (x) : (y)
+
+#define SUB_VERSION	0
+
+/* max number of devices supported by driver */
+#define MAX_DEVICE_NUM	1
+
 enum log_level  {
 	MV_LOG_LEVEL_0,
 	MV_LOG_LEVEL_1,
@@ -151,28 +49,27 @@ enum log_level  {
 };
 
 /* Globals */
-extern u8 debug_training;
+extern u8 debug_training, debug_calibration, debug_ddr4_centralization,
+	debug_tap_tuning, debug_dm_tuning;
 extern u8 is_reg_dump;
 extern u8 generic_init_controller;
-extern u32 freq_val[];
+/* list of allowed frequency listed in order of enum hws_ddr_freq */
+extern u32 freq_val[DDR_FREQ_LAST];
 extern u32 is_pll_old;
 extern struct cl_val_per_freq cas_latency_table[];
 extern struct pattern_info pattern_table[];
 extern struct cl_val_per_freq cas_write_latency_table[];
-extern u8 debug_training;
 extern u8 debug_centralization, debug_training_ip, debug_training_bist,
 	debug_pbs, debug_training_static, debug_leveling;
-extern u32 pipe_multicast_mask;
 extern struct hws_tip_config_func_db config_func_info[];
-extern u8 cs_mask_reg[];
 extern u8 twr_mask_table[];
 extern u8 cl_mask_table[];
 extern u8 cwl_mask_table[];
 extern u16 rfc_table[];
 extern u32 speed_bin_table_t_rc[];
 extern u32 speed_bin_table_t_rcd_t_rp[];
-extern u32 ck_delay, ck_delay_16;
 
+extern u32 vref_init_val;
 extern u32 g_zpri_data;
 extern u32 g_znri_data;
 extern u32 g_zpri_ctrl;
@@ -182,39 +79,28 @@ extern u32 g_znodt_data;
 extern u32 g_zpodt_ctrl;
 extern u32 g_znodt_ctrl;
 extern u32 g_dic;
-extern u32 g_odt_config_2cs;
-extern u32 g_odt_config_1cs;
+extern u32 g_odt_config;
 extern u32 g_rtt_nom;
+extern u32 g_rtt_wr;
+extern u32 g_rtt_park;
 
 extern u8 debug_training_access;
-extern u8 debug_training_a38x;
 extern u32 first_active_if;
-extern enum hws_ddr_freq init_freq;
-extern u32 delay_enable, ck_delay, ck_delay_16, ca_delay;
+extern u32 delay_enable, ck_delay, ca_delay;
 extern u32 mask_tune_func;
 extern u32 rl_version;
 extern int rl_mid_freq_wa;
 extern u8 calibration_update_control; /* 2 external only, 1 is internal only */
 extern enum hws_ddr_freq medium_freq;
 
-extern u32 ck_delay, ck_delay_16;
 extern enum hws_result training_result[MAX_STAGE_LIMIT][MAX_INTERFACE_NUM];
-extern u32 first_active_if;
-extern u32 mask_tune_func;
-extern u32 freq_val[];
-extern enum hws_ddr_freq init_freq;
 extern enum hws_ddr_freq low_freq;
-extern enum hws_ddr_freq medium_freq;
-extern u8 generic_init_controller;
 extern enum auto_tune_stage training_stage;
 extern u32 is_pll_before_init;
 extern u32 is_adll_calib_before_init;
 extern u32 is_dfs_in_init;
 extern int wl_debug_delay;
-extern u32 silicon_delay[HWS_MAX_DEVICE_NUM];
-extern u32 p_finger;
-extern u32 n_finger;
-extern u32 freq_val[DDR_FREQ_LIMIT];
+extern u32 silicon_delay[MAX_DEVICE_NUM];
 extern u32 start_pattern, end_pattern;
 extern u32 phy_reg0_val;
 extern u32 phy_reg1_val;
@@ -222,172 +108,93 @@ extern u32 phy_reg2_val;
 extern u32 phy_reg3_val;
 extern enum hws_pattern sweep_pattern;
 extern enum hws_pattern pbs_pattern;
-extern u8 is_rzq6;
-extern u32 znri_data_phy_val;
-extern u32 zpri_data_phy_val;
-extern u32 znri_ctrl_phy_val;
-extern u32 zpri_ctrl_phy_val;
-extern u8 debug_training_access;
+extern u32 g_znri_data;
+extern u32 g_zpri_data;
+extern u32 g_znri_ctrl;
+extern u32 g_zpri_ctrl;
 extern u32 finger_test, p_finger_start, p_finger_end, n_finger_start,
 	n_finger_end, p_finger_step, n_finger_step;
-extern u32 mode2_t;
+extern u32 mode_2t;
 extern u32 xsb_validate_type;
 extern u32 xsb_validation_base_address;
 extern u32 odt_additional;
 extern u32 debug_mode;
-extern u32 delay_enable;
-extern u32 ca_delay;
 extern u32 debug_dunit;
 extern u32 clamp_tbl[];
-extern u32 freq_mask[HWS_MAX_DEVICE_NUM][DDR_FREQ_LIMIT];
-extern u32 start_pattern, end_pattern;
+extern u32 freq_mask[MAX_DEVICE_NUM][DDR_FREQ_LAST];
 
 extern u32 maxt_poll_tries;
 extern u32 is_bist_reset_bit;
-extern u8 debug_training_bist;
 
 extern u8 vref_window_size[MAX_INTERFACE_NUM][MAX_BUS_NUM];
-extern u32 debug_mode;
 extern u32 effective_cs;
 extern int ddr3_tip_centr_skip_min_win_check;
 extern u32 *dq_map_table;
-extern enum auto_tune_stage training_stage;
-extern u8 debug_centralization;
 
-extern u32 delay_enable;
-extern u32 start_pattern, end_pattern;
-extern u32 freq_val[DDR_FREQ_LIMIT];
 extern u8 debug_training_hw_alg;
-extern enum auto_tune_stage training_stage;
 
-extern u8 debug_training_ip;
-extern enum hws_result training_result[MAX_STAGE_LIMIT][MAX_INTERFACE_NUM];
-extern enum auto_tune_stage training_stage;
-extern u32 effective_cs;
-
-extern u8 debug_leveling;
-extern enum hws_result training_result[MAX_STAGE_LIMIT][MAX_INTERFACE_NUM];
-extern enum auto_tune_stage training_stage;
-extern u32 rl_version;
-extern struct cl_val_per_freq cas_latency_table[];
 extern u32 start_xsb_offset;
-extern u32 debug_mode;
 extern u32 odt_config;
-extern u32 effective_cs;
-extern u32 phy_reg1_val;
 
-extern u8 debug_pbs;
-extern u32 effective_cs;
 extern u16 mask_results_dq_reg_map[];
-extern enum hws_ddr_freq medium_freq;
-extern u32 freq_val[];
-extern enum hws_result training_result[MAX_STAGE_LIMIT][MAX_INTERFACE_NUM];
-extern enum auto_tune_stage training_stage;
-extern u32 debug_mode;
-extern u32 *dq_map_table;
 
-extern u32 vref;
-extern struct cl_val_per_freq cas_latency_table[];
 extern u32 target_freq;
-extern struct hws_tip_config_func_db config_func_info[HWS_MAX_DEVICE_NUM];
-extern u32 clamp_tbl[];
-extern u32 init_freq;
-/* list of allowed frequency listed in order of enum hws_ddr_freq */
-extern u32 freq_val[];
-extern u8 debug_training_static;
-extern u32 first_active_if;
+extern u32 dfs_low_freq;
+extern u32 mem_size[];
+
+extern u32 nominal_avs;
+extern u32 extension_avs;
+
 
 /* Prototypes */
+int ddr3_init(void);
 int ddr3_tip_enable_init_sequence(u32 dev_num);
 
-int ddr3_tip_init_a38x(u32 dev_num, u32 board_id);
-
-int ddr3_hws_hw_training(void);
-int ddr3_silicon_pre_init(void);
+int ddr3_hws_hw_training(enum hws_algo_type algo_mode);
+int mv_ddr_early_init(void);
+int mv_ddr_early_init2(void);
 int ddr3_silicon_post_init(void);
 int ddr3_post_run_alg(void);
 int ddr3_if_ecc_enabled(void);
 void ddr3_new_tip_ecc_scrub(void);
 
-void ddr3_print_version(void);
-void ddr3_new_tip_dlb_config(void);
-struct hws_topology_map *ddr3_get_topology_map(void);
+void mv_ddr_ver_print(void);
+struct mv_ddr_topology_map *mv_ddr_topology_map_get(void);
 
 int ddr3_if_ecc_enabled(void);
 int ddr3_tip_reg_write(u32 dev_num, u32 reg_addr, u32 data);
 int ddr3_tip_reg_read(u32 dev_num, u32 reg_addr, u32 *data, u32 reg_mask);
 int ddr3_silicon_get_ddr_target_freq(u32 *ddr_freq);
-int ddr3_tip_a38x_get_freq_config(u8 dev_num, enum hws_ddr_freq freq,
-				  struct hws_tip_freq_config_info
-				  *freq_config_info);
-int ddr3_a38x_update_topology_map(u32 dev_num,
-				  struct hws_topology_map *topology_map);
-int ddr3_tip_a38x_get_init_freq(int dev_num, enum hws_ddr_freq *freq);
-int ddr3_tip_a38x_get_medium_freq(int dev_num, enum hws_ddr_freq *freq);
-int ddr3_tip_a38x_if_read(u8 dev_num, enum hws_access_type interface_access,
-			  u32 if_id, u32 reg_addr, u32 *data, u32 mask);
-int ddr3_tip_a38x_if_write(u8 dev_num, enum hws_access_type interface_access,
-			   u32 if_id, u32 reg_addr, u32 data, u32 mask);
-int ddr3_tip_a38x_get_device_info(u8 dev_num,
-				  struct ddr3_device_info *info_ptr);
-
-int ddr3_tip_init_a38x(u32 dev_num, u32 board_id);
 
 int print_adll(u32 dev_num, u32 adll[MAX_INTERFACE_NUM * MAX_BUS_NUM]);
+int print_ph(u32 dev_num, u32 adll[MAX_INTERFACE_NUM * MAX_BUS_NUM]);
+int read_phase_value(u32 dev_num, u32 pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
+		     int reg_addr, u32 mask);
+int write_leveling_value(u32 dev_num, u32 pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
+			 u32 pup_ph_values[MAX_INTERFACE_NUM * MAX_BUS_NUM], int reg_addr);
 int ddr3_tip_restore_dunit_regs(u32 dev_num);
-void print_topology(struct hws_topology_map *topology_db);
+void print_topology(struct mv_ddr_topology_map *tm);
 
 u32 mv_board_id_get(void);
 
 int ddr3_load_topology_map(void);
-int ddr3_tip_init_specific_reg_config(u32 dev_num,
-				      struct reg_data *reg_config_arr);
-u32 ddr3_tip_get_init_freq(void);
 void ddr3_hws_set_log_level(enum ddr_lib_debug_block block, u8 level);
+void mv_ddr_user_log_level_set(enum ddr_lib_debug_block block);
 int ddr3_tip_tune_training_params(u32 dev_num,
 				  struct tune_train_params *params);
 void get_target_freq(u32 freq_mode, u32 *ddr_freq, u32 *hclk_ps);
-int ddr3_fast_path_dynamic_cs_size_config(u32 cs_ena);
 void ddr3_fast_path_static_cs_size_config(u32 cs_ena);
-u32 ddr3_get_device_width(u32 cs);
 u32 mv_board_id_index_get(u32 board_id);
-u32 mv_board_id_get(void);
-u32 ddr3_get_bus_width(void);
 void ddr3_set_log_level(u32 n_log_level);
-int ddr3_calc_mem_cs_size(u32 cs, u32 *cs_size);
+int calc_cs_num(u32 dev_num, u32 if_id, u32 *cs_num);
 
 int hws_ddr3_cs_base_adr_calc(u32 if_id, u32 cs, u32 *cs_base_addr);
 
 int ddr3_tip_print_pbs_result(u32 dev_num, u32 cs_num, enum pbs_dir pbs_mode);
 int ddr3_tip_clean_pbs_result(u32 dev_num, enum pbs_dir pbs_mode);
 
-int ddr3_tip_static_round_trip_arr_build(u32 dev_num,
-					 struct trip_delay_element *table_ptr,
-					 int is_wl, u32 *round_trip_delay_arr);
-
-u32 hws_ddr3_tip_max_cs_get(void);
-
-/*
- * Accessor functions for the registers
- */
-static inline void reg_write(u32 addr, u32 val)
-{
-	writel(val, INTER_REGS_BASE + addr);
-}
-
-static inline u32 reg_read(u32 addr)
-{
-	return readl(INTER_REGS_BASE + addr);
-}
-
-static inline void reg_bit_set(u32 addr, u32 mask)
-{
-	setbits_le32(INTER_REGS_BASE + addr, mask);
-}
-
-static inline void reg_bit_clr(u32 addr, u32 mask)
-{
-	clrbits_le32(INTER_REGS_BASE + addr, mask);
-}
-
+u32 mv_ddr_init_freq_get(void);
+void mv_ddr_mc_config(void);
+int mv_ddr_mc_init(void);
+void mv_ddr_set_calib_controller(void);
 #endif /* _DDR3_INIT_H */
diff --git a/drivers/ddr/marvell/a38x/ddr3_logging_def.h b/drivers/ddr/marvell/a38x/ddr3_logging_def.h
index 2de7c4fa312b..7c90ba5ea38b 100644
--- a/drivers/ddr/marvell/a38x/ddr3_logging_def.h
+++ b/drivers/ddr/marvell/a38x/ddr3_logging_def.h
@@ -74,10 +74,14 @@
 #endif
 #endif
 
+
 /* Logging defines */
-#define DEBUG_LEVEL_TRACE	1
-#define DEBUG_LEVEL_INFO	2
-#define DEBUG_LEVEL_ERROR	3
+enum mv_ddr_debug_level {
+	DEBUG_LEVEL_TRACE = 1,
+	DEBUG_LEVEL_INFO = 2,
+	DEBUG_LEVEL_ERROR = 3,
+	DEBUG_LEVEL_LAST
+};
 
 enum ddr_lib_debug_block {
 	DEBUG_BLOCK_STATIC,
diff --git a/drivers/ddr/marvell/a38x/ddr3_patterns_64bit.h b/drivers/ddr/marvell/a38x/ddr3_patterns_64bit.h
index 0ce0479a3ab6..257470113559 100644
--- a/drivers/ddr/marvell/a38x/ddr3_patterns_64bit.h
+++ b/drivers/ddr/marvell/a38x/ddr3_patterns_64bit.h
@@ -7,6 +7,7 @@
 #ifndef __DDR3_PATTERNS_64_H
 #define __DDR3_PATTERNS_64_H
 
+#define FAB_OPT		21
 /*
  * Patterns Declerations
  */
diff --git a/drivers/ddr/marvell/a38x/ddr3_topology_def.h b/drivers/ddr/marvell/a38x/ddr3_topology_def.h
index a17eca041878..87f6c88ade16 100644
--- a/drivers/ddr/marvell/a38x/ddr3_topology_def.h
+++ b/drivers/ddr/marvell/a38x/ddr3_topology_def.h
@@ -7,8 +7,9 @@
 #ifndef _DDR3_TOPOLOGY_DEF_H
 #define _DDR3_TOPOLOGY_DEF_H
 
-/* TOPOLOGY */
+#define DEV_NUM_0	0
 
+/* TOPOLOGY */
 enum hws_speed_bin {
 	SPEED_BIN_DDR_800D,
 	SPEED_BIN_DDR_800E,
@@ -54,7 +55,8 @@ enum hws_ddr_freq {
 	DDR_FREQ_900,
 	DDR_FREQ_360,
 	DDR_FREQ_1000,
-	DDR_FREQ_LIMIT
+	DDR_FREQ_LAST,
+	DDR_FREQ_SAR
 };
 
 enum speed_bin_table_elements {
diff --git a/drivers/ddr/marvell/a38x/ddr3_training.c b/drivers/ddr/marvell/a38x/ddr3_training.c
index f9e11591d992..0b414aba1fda 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training.c
+++ b/drivers/ddr/marvell/a38x/ddr3_training.c
@@ -4,48 +4,35 @@
  * SPDX-License-Identifier:	GPL-2.0
  */
 
-#include <common.h>
-#include <spl.h>
-#include <asm/io.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/soc.h>
-
 #include "ddr3_init.h"
-
-#define GET_MAX_VALUE(x, y)			\
-	((x) > (y)) ? (x) : (y)
-#define CEIL_DIVIDE(x, y)					\
-	((x - (x / y) * y) == 0) ? ((x / y) - 1) : (x / y)
-
-#define TIME_2_CLOCK_CYCLES	CEIL_DIVIDE
+#include "mv_ddr_common.h"
 
 #define GET_CS_FROM_MASK(mask)	(cs_mask2_num[mask])
 #define CS_CBE_VALUE(cs_num)	(cs_cbe_reg[cs_num])
 
-#define TIMES_9_TREFI_CYCLES	0x8
-
 u32 window_mem_addr = 0;
 u32 phy_reg0_val = 0;
 u32 phy_reg1_val = 8;
 u32 phy_reg2_val = 0;
-u32 phy_reg3_val = 0xa;
-enum hws_ddr_freq init_freq = DDR_FREQ_667;
+u32 phy_reg3_val = PARAM_UNDEFINED;
 enum hws_ddr_freq low_freq = DDR_FREQ_LOW_FREQ;
 enum hws_ddr_freq medium_freq;
 u32 debug_dunit = 0;
 u32 odt_additional = 1;
 u32 *dq_map_table = NULL;
+
+/* in case of ddr4 do not run ddr3_tip_write_additional_odt_setting function - mc odt always 'on'
+ * in ddr4 case the terminations are rttWR and rttPARK and the odt must be always 'on' 0x1498 = 0xf
+ */
 u32 odt_config = 1;
 
-#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ALLEYCAT3) ||	\
-	defined(CONFIG_ARMADA_39X)
-u32 is_pll_before_init = 0, is_adll_calib_before_init = 0, is_dfs_in_init = 0;
-u32 dfs_low_freq = 130;
-#else
+u32 nominal_avs;
+u32 extension_avs;
+
 u32 is_pll_before_init = 0, is_adll_calib_before_init = 1, is_dfs_in_init = 0;
-u32 dfs_low_freq = 100;
-#endif
-u32 g_rtt_nom_c_s0, g_rtt_nom_c_s1;
+u32 dfs_low_freq;
+
+u32 g_rtt_nom_cs0, g_rtt_nom_cs1;
 u8 calibration_update_control;	/* 2 external only, 1 is internal only */
 
 enum hws_result training_result[MAX_STAGE_LIMIT][MAX_INTERFACE_NUM];
@@ -56,7 +43,7 @@ u32 finger_test = 0, p_finger_start = 11, p_finger_end = 64,
 u32 clamp_tbl[] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
 
 /* Initiate to 0xff, this variable is define by user in debug mode */
-u32 mode2_t = 0xff;
+u32 mode_2t = 0xff;
 u32 xsb_validate_type = 0;
 u32 xsb_validation_base_address = 0xf000;
 u32 first_active_if = 0;
@@ -71,25 +58,41 @@ int rl_mid_freq_wa = 0;
 
 u32 effective_cs = 0;
 
+u32 vref_init_val = 0x4;
+u32 ck_delay = PARAM_UNDEFINED;
+
+/* Design guidelines parameters */
+u32 g_zpri_data = PARAM_UNDEFINED; /* controller data - P drive strength */
+u32 g_znri_data = PARAM_UNDEFINED; /* controller data - N drive strength */
+u32 g_zpri_ctrl = PARAM_UNDEFINED; /* controller C/A - P drive strength */
+u32 g_znri_ctrl = PARAM_UNDEFINED; /* controller C/A - N drive strength */
+
+u32 g_zpodt_data = PARAM_UNDEFINED; /* controller data - P ODT */
+u32 g_znodt_data = PARAM_UNDEFINED; /* controller data - N ODT */
+u32 g_zpodt_ctrl = PARAM_UNDEFINED; /* controller data - P ODT */
+u32 g_znodt_ctrl = PARAM_UNDEFINED; /* controller data - N ODT */
+
+u32 g_odt_config = PARAM_UNDEFINED;
+u32 g_rtt_nom = PARAM_UNDEFINED;
+u32 g_rtt_wr = PARAM_UNDEFINED;
+u32 g_dic = PARAM_UNDEFINED;
+u32 g_rtt_park = PARAM_UNDEFINED;
+
 u32 mask_tune_func = (SET_MEDIUM_FREQ_MASK_BIT |
 		      WRITE_LEVELING_MASK_BIT |
 		      LOAD_PATTERN_2_MASK_BIT |
 		      READ_LEVELING_MASK_BIT |
-		      SET_TARGET_FREQ_MASK_BIT | WRITE_LEVELING_TF_MASK_BIT |
+		      SET_TARGET_FREQ_MASK_BIT |
+		      WRITE_LEVELING_TF_MASK_BIT |
 		      READ_LEVELING_TF_MASK_BIT |
-		      CENTRALIZATION_RX_MASK_BIT | CENTRALIZATION_TX_MASK_BIT);
-
-void ddr3_print_version(void)
-{
-	printf(DDR3_TIP_VERSION_STRING);
-}
+		      CENTRALIZATION_RX_MASK_BIT |
+		      CENTRALIZATION_TX_MASK_BIT);
 
 static int ddr3_tip_ddr3_training_main_flow(u32 dev_num);
 static int ddr3_tip_write_odt(u32 dev_num, enum hws_access_type access_type,
 			      u32 if_id, u32 cl_value, u32 cwl_value);
 static int ddr3_tip_ddr3_auto_tune(u32 dev_num);
-static int is_bus_access_done(u32 dev_num, u32 if_id,
-			      u32 dunit_reg_adrr, u32 bit);
+
 #ifdef ODT_TEST_SUPPORT
 static int odt_test(u32 dev_num, enum hws_algo_type algo_type);
 #endif
@@ -99,7 +102,7 @@ int adll_calibration(u32 dev_num, enum hws_access_type access_type,
 static int ddr3_tip_set_timing(u32 dev_num, enum hws_access_type access_type,
 			       u32 if_id, enum hws_ddr_freq frequency);
 
-static struct page_element page_param[] = {
+static struct page_element page_tbl[] = {
 	/*
 	 * 8bits	16 bits
 	 * page-size(K)	page-size(K)	mask
@@ -112,16 +115,30 @@ static struct page_element page_param[] = {
 	/* 2G */
 	{ 1,		2,		4},
 	/* 4G */
-	{ 2,		2,		5}
+	{ 2,		2,		5},
 	/* 8G */
+	{0, 0, 0}, /* TODO: placeholder for 16-Mbit die capacity */
+	{0, 0, 0}, /* TODO: placeholder for 32-Mbit die capacity */
+	{0, 0, 0}, /* TODO: placeholder for 12-Mbit die capacity */
+	{0, 0, 0}  /* TODO: placeholder for 24-Mbit die capacity */
+
 };
 
-static u8 mem_size_config[MEM_SIZE_LAST] = {
+struct page_element *mv_ddr_page_tbl_get(void)
+{
+	return &page_tbl[0];
+}
+
+static u8 mem_size_config[MV_DDR_DIE_CAP_LAST] = {
 	0x2,			/* 512Mbit  */
 	0x3,			/* 1Gbit    */
 	0x0,			/* 2Gbit    */
 	0x4,			/* 4Gbit    */
-	0x5			/* 8Gbit    */
+	0x5,			/* 8Gbit    */
+	0x0, /* TODO: placeholder for 16-Mbit die capacity */
+	0x0, /* TODO: placeholder for 32-Mbit die capacity */
+	0x0, /* TODO: placeholder for 12-Mbit die capacity */
+	0x0  /* TODO: placeholder for 24-Mbit die capacity */
 };
 
 static u8 cs_mask2_num[] = { 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 };
@@ -180,10 +197,14 @@ static struct reg_data odpg_default_value[] = {
 	{0x16fc, 0x0, MASK_ALL_BITS}
 };
 
-static int ddr3_tip_bus_access(u32 dev_num, enum hws_access_type interface_access,
-			       u32 if_id, enum hws_access_type phy_access,
-			       u32 phy_id, enum hws_ddr_phy phy_type, u32 reg_addr,
-			       u32 data_value, enum hws_operation oper_type);
+/* MR cmd and addr definitions */
+struct mv_ddr_mr_data mr_data[] = {
+	{MRS0_CMD, MR0_REG},
+	{MRS1_CMD, MR1_REG},
+	{MRS2_CMD, MR2_REG},
+	{MRS3_CMD, MR3_REG}
+};
+
 static int ddr3_tip_pad_inv(u32 dev_num, u32 if_id);
 static int ddr3_tip_rank_control(u32 dev_num, u32 if_id);
 
@@ -193,12 +214,41 @@ static int ddr3_tip_rank_control(u32 dev_num, u32 if_id);
 int ddr3_tip_tune_training_params(u32 dev_num,
 				  struct tune_train_params *params)
 {
-	if (params->ck_delay != -1)
+	if (params->ck_delay != PARAM_UNDEFINED)
 		ck_delay = params->ck_delay;
-	if (params->ck_delay_16 != -1)
-		ck_delay_16 = params->ck_delay_16;
-	if (params->phy_reg3_val != -1)
+	if (params->phy_reg3_val != PARAM_UNDEFINED)
 		phy_reg3_val = params->phy_reg3_val;
+	if (params->g_rtt_nom != PARAM_UNDEFINED)
+		g_rtt_nom = params->g_rtt_nom;
+	if (params->g_rtt_wr != PARAM_UNDEFINED)
+		g_rtt_wr = params->g_rtt_wr;
+	if (params->g_dic != PARAM_UNDEFINED)
+		g_dic = params->g_dic;
+	if (params->g_odt_config != PARAM_UNDEFINED)
+		g_odt_config = params->g_odt_config;
+	if (params->g_zpri_data != PARAM_UNDEFINED)
+		g_zpri_data = params->g_zpri_data;
+	if (params->g_znri_data != PARAM_UNDEFINED)
+		g_znri_data = params->g_znri_data;
+	if (params->g_zpri_ctrl != PARAM_UNDEFINED)
+		g_zpri_ctrl = params->g_zpri_ctrl;
+	if (params->g_znri_ctrl != PARAM_UNDEFINED)
+		g_znri_ctrl = params->g_znri_ctrl;
+	if (params->g_zpodt_data != PARAM_UNDEFINED)
+		g_zpodt_data = params->g_zpodt_data;
+	if (params->g_znodt_data != PARAM_UNDEFINED)
+		g_znodt_data = params->g_znodt_data;
+	if (params->g_zpodt_ctrl != PARAM_UNDEFINED)
+		g_zpodt_ctrl = params->g_zpodt_ctrl;
+	if (params->g_znodt_ctrl != PARAM_UNDEFINED)
+		g_znodt_ctrl = params->g_znodt_ctrl;
+	if (params->g_rtt_park != PARAM_UNDEFINED)
+		g_rtt_park = params->g_rtt_park;
+
+	DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+			  ("DGL parameters: 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n",
+			   g_zpri_data, g_znri_data, g_zpri_ctrl, g_znri_ctrl, g_zpodt_data, g_znodt_data,
+			   g_zpodt_ctrl, g_znodt_ctrl, g_rtt_nom, g_dic, g_odt_config, g_rtt_wr));
 
 	return MV_OK;
 }
@@ -210,34 +260,34 @@ int ddr3_tip_configure_cs(u32 dev_num, u32 if_id, u32 cs_num, u32 enable)
 {
 	u32 data, addr_hi, data_high;
 	u32 mem_index;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	if (enable == 1) {
 		data = (tm->interface_params[if_id].bus_width ==
-			BUS_WIDTH_8) ? 0 : 1;
+			MV_DDR_DEV_WIDTH_8BIT) ? 0 : 1;
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      SDRAM_ACCESS_CONTROL_REG, (data << (cs_num * 4)),
+			      SDRAM_ADDR_CTRL_REG, (data << (cs_num * 4)),
 			      0x3 << (cs_num * 4)));
 		mem_index = tm->interface_params[if_id].memory_size;
 
 		addr_hi = mem_size_config[mem_index] & 0x3;
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      SDRAM_ACCESS_CONTROL_REG,
+			      SDRAM_ADDR_CTRL_REG,
 			      (addr_hi << (2 + cs_num * 4)),
 			      0x3 << (2 + cs_num * 4)));
 
 		data_high = (mem_size_config[mem_index] & 0x4) >> 2;
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      SDRAM_ACCESS_CONTROL_REG,
+			      SDRAM_ADDR_CTRL_REG,
 			      data_high << (20 + cs_num), 1 << (20 + cs_num)));
 
 		/* Enable Address Select Mode */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      SDRAM_ACCESS_CONTROL_REG, 1 << (16 + cs_num),
+			      SDRAM_ADDR_CTRL_REG, 1 << (16 + cs_num),
 			      1 << (16 + cs_num)));
 	}
 	switch (cs_num) {
@@ -246,13 +296,13 @@ int ddr3_tip_configure_cs(u32 dev_num, u32 if_id, u32 cs_num, u32 enable)
 	case 2:
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      DDR_CONTROL_LOW_REG, (enable << (cs_num + 11)),
+			      DUNIT_CTRL_LOW_REG, (enable << (cs_num + 11)),
 			      1 << (cs_num + 11)));
 		break;
 	case 3:
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      DDR_CONTROL_LOW_REG, (enable << 15), 1 << 15));
+			      DUNIT_CTRL_LOW_REG, (enable << 15), 1 << 15));
 		break;
 	}
 
@@ -262,17 +312,18 @@ int ddr3_tip_configure_cs(u32 dev_num, u32 if_id, u32 cs_num, u32 enable)
 /*
  * Calculate number of CS
  */
-static int calc_cs_num(u32 dev_num, u32 if_id, u32 *cs_num)
+int calc_cs_num(u32 dev_num, u32 if_id, u32 *cs_num)
 {
 	u32 cs;
 	u32 bus_cnt;
 	u32 cs_count;
 	u32 cs_bitmask;
 	u32 curr_cs_num = 0;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
-	for (bus_cnt = 0; bus_cnt < GET_TOPOLOGY_NUM_OF_BUSES(); bus_cnt++) {
-		VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
+	for (bus_cnt = 0; bus_cnt < octets_per_if_num; bus_cnt++) {
+		VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_cnt);
 		cs_count = 0;
 		cs_bitmask = tm->interface_params[if_id].
 			as_bus_params[bus_cnt].cs_bitmask;
@@ -303,21 +354,18 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_
 {
 	u32 if_id;
 	u32 cs_num;
-	u32 t_refi = 0, t_hclk = 0, t_ckclk = 0, t_faw = 0, t_pd = 0,
-		t_wr = 0, t2t = 0, txpdll = 0;
-	u32 data_value = 0, bus_width = 0, page_size = 0, cs_cnt = 0,
+	u32 t_ckclk = 0, t_wr = 0, t2t = 0;
+	u32 data_value = 0, cs_cnt = 0,
 		mem_mask = 0, bus_index = 0;
 	enum hws_speed_bin speed_bin_index = SPEED_BIN_DDR_2133N;
-	enum hws_mem_size memory_size = MEM_2G;
-	enum hws_ddr_freq freq = init_freq;
-	enum hws_timing timing;
 	u32 cs_mask = 0;
 	u32 cl_value = 0, cwl_val = 0;
-	u32 refresh_interval_cnt = 0, bus_cnt = 0, adll_tap = 0;
+	u32 bus_cnt = 0, adll_tap = 0;
 	enum hws_access_type access_type = ACCESS_TYPE_UNICAST;
 	u32 data_read[MAX_INTERFACE_NUM];
-	struct hws_topology_map *tm = ddr3_get_topology_map();
-	u32 odt_config = g_odt_config_2cs;
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+	enum hws_ddr_freq freq = tm->interface_params[0].memory_freq;
 
 	DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
 			  ("Init_controller, do_mrs_phy=%d, is_ctrl64_bit=%d\n",
@@ -330,14 +378,14 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_
 
 	if (generic_init_controller == 1) {
 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 			DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
 					  ("active IF %d\n", if_id));
 			mem_mask = 0;
 			for (bus_index = 0;
-			     bus_index < GET_TOPOLOGY_NUM_OF_BUSES();
+			     bus_index < octets_per_if_num;
 			     bus_index++) {
-				VALIDATE_ACTIVE(tm->bus_act_mask, bus_index);
+				VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_index);
 				mem_mask |=
 					tm->interface_params[if_id].
 					as_bus_params[bus_index].mirror_enable_bitmask;
@@ -346,57 +394,46 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_
 			if (mem_mask != 0) {
 				CHECK_STATUS(ddr3_tip_if_write
 					     (dev_num, ACCESS_TYPE_MULTICAST,
-					      if_id, CS_ENABLE_REG, 0,
+					      if_id, DUAL_DUNIT_CFG_REG, 0,
 					      0x8));
 			}
 
-			memory_size =
-				tm->interface_params[if_id].
-				memory_size;
 			speed_bin_index =
 				tm->interface_params[if_id].
 				speed_bin_index;
-			freq = init_freq;
-			t_refi =
-				(tm->interface_params[if_id].
-				 interface_temp ==
-				 HWS_TEMP_HIGH) ? TREFI_HIGH : TREFI_LOW;
-			t_refi *= 1000;	/* psec */
-			DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
-					  ("memy_size %d speed_bin_ind %d freq %d t_refi %d\n",
-					   memory_size, speed_bin_index, freq,
-					   t_refi));
-			/* HCLK & CK CLK in 2:1[ps] */
+
 			/* t_ckclk is external clock */
 			t_ckclk = (MEGA / freq_val[freq]);
-			/* t_hclk is internal clock */
-			t_hclk = 2 * t_ckclk;
-			refresh_interval_cnt = t_refi / t_hclk;	/* no units */
-			bus_width =
-				(DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask)
-				 == 1) ? (16) : (32);
-
-			if (init_cntr_prm->is_ctrl64_bit)
-				bus_width = 64;
 
-			data_value =
-				(refresh_interval_cnt | 0x4000 |
-				 ((bus_width ==
-				   32) ? 0x8000 : 0) | 0x1000000) & ~(1 << 26);
+			if (MV_DDR_IS_HALF_BUS_DRAM_MODE(tm->bus_act_mask, octets_per_if_num))
+				data_value = (0x4000 | 0 | 0x1000000) & ~(1 << 26);
+			else
+				data_value = (0x4000 | 0x8000 | 0x1000000) & ~(1 << 26);
 
 			/* Interface Bus Width */
 			/* SRMode */
 			CHECK_STATUS(ddr3_tip_if_write
 				     (dev_num, access_type, if_id,
-				      SDRAM_CONFIGURATION_REG, data_value,
-				      0x100ffff));
+				      SDRAM_CFG_REG, data_value,
+				      0x100c000));
 
 			/* Interleave first command pre-charge enable (TBD) */
 			CHECK_STATUS(ddr3_tip_if_write
 				     (dev_num, access_type, if_id,
-				      SDRAM_OPEN_PAGE_CONTROL_REG, (1 << 10),
+				      SDRAM_OPEN_PAGES_CTRL_REG, (1 << 10),
 				      (1 << 10)));
 
+			/* Reset divider_b assert -> de-assert */
+			CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
+						       SDRAM_CFG_REG,
+						       0x0 << PUP_RST_DIVIDER_OFFS,
+						       PUP_RST_DIVIDER_MASK << PUP_RST_DIVIDER_OFFS));
+
+			CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
+						       SDRAM_CFG_REG,
+						       0x1 << PUP_RST_DIVIDER_OFFS,
+						       PUP_RST_DIVIDER_MASK << PUP_RST_DIVIDER_OFFS));
+
 			/* PHY configuration */
 			/*
 			 * Postamble Length = 1.5cc, Addresscntl to clk skew
@@ -404,12 +441,12 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_
 			 */
 			CHECK_STATUS(ddr3_tip_if_write
 				     (dev_num, access_type, if_id,
-				      DRAM_PHY_CONFIGURATION, 0x28, 0x3e));
+				      DRAM_PHY_CFG_REG, 0x28, 0x3e));
 			if (init_cntr_prm->is_ctrl64_bit) {
 				/* positive edge */
 				CHECK_STATUS(ddr3_tip_if_write
 					     (dev_num, access_type, if_id,
-					      DRAM_PHY_CONFIGURATION, 0x0,
+					      DRAM_PHY_CFG_REG, 0x0,
 					      0xff80));
 			}
 
@@ -417,17 +454,24 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_
 			/* Xbar Read buffer select (for Internal access) */
 			CHECK_STATUS(ddr3_tip_if_write
 				     (dev_num, access_type, if_id,
-				      CALIB_MACHINE_CTRL_REG, 0x1200c,
+				      MAIN_PADS_CAL_MACH_CTRL_REG, 0x1200c,
 				      0x7dffe01c));
 			CHECK_STATUS(ddr3_tip_if_write
 				     (dev_num, access_type, if_id,
-				      CALIB_MACHINE_CTRL_REG,
+				      MAIN_PADS_CAL_MACH_CTRL_REG,
 				      calibration_update_control << 3, 0x3 << 3));
 
 			/* Pad calibration control - enable */
 			CHECK_STATUS(ddr3_tip_if_write
 				     (dev_num, access_type, if_id,
-				      CALIB_MACHINE_CTRL_REG, 0x1, 0x1));
+				      MAIN_PADS_CAL_MACH_CTRL_REG, 0x1, 0x1));
+			if (ddr3_tip_dev_attr_get(dev_num, MV_ATTR_TIP_REV) < MV_TIP_REV_3) {
+				/* DDR3 rank ctrl \96 part of the generic code */
+				/* CS1 mirroring enable + w/a for JIRA DUNIT-14581 */
+				CHECK_STATUS(ddr3_tip_if_write
+					     (dev_num, access_type, if_id,
+					      DDR3_RANK_CTRL_REG, 0x27, MASK_ALL_BITS));
+			}
 
 			cs_mask = 0;
 			data_value = 0x7;
@@ -438,40 +482,19 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_
 			 * 2) Bus_width
 			 * 3) CS#
 			 * 4) Page Number
-			 * 5) t_faw
 			 * Per Dunit get from the Map_topology the parameters:
 			 * Bus_width
-			 * t_faw is per Dunit not per CS
 			 */
-			page_size =
-				(tm->interface_params[if_id].
-				 bus_width ==
-				 BUS_WIDTH_8) ? page_param[memory_size].
-				page_size_8bit : page_param[memory_size].
-				page_size_16bit;
-
-			t_faw =
-				(page_size == 1) ? speed_bin_table(speed_bin_index,
-								   SPEED_BIN_TFAW1K)
-				: speed_bin_table(speed_bin_index,
-						  SPEED_BIN_TFAW2K);
-
-			data_value = TIME_2_CLOCK_CYCLES(t_faw, t_ckclk);
-			data_value = data_value << 24;
-			CHECK_STATUS(ddr3_tip_if_write
-				     (dev_num, access_type, if_id,
-				      SDRAM_ACCESS_CONTROL_REG, data_value,
-				      0x7f000000));
 
 			data_value =
 				(tm->interface_params[if_id].
-				 bus_width == BUS_WIDTH_8) ? 0 : 1;
+				 bus_width == MV_DDR_DEV_WIDTH_8BIT) ? 0 : 1;
 
 			/* create merge cs mask for all cs available in dunit */
 			for (bus_cnt = 0;
-			     bus_cnt < GET_TOPOLOGY_NUM_OF_BUSES();
+			     bus_cnt < octets_per_if_num;
 			     bus_cnt++) {
-				VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
+				VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_cnt);
 				cs_mask |=
 					tm->interface_params[if_id].
 					as_bus_params[bus_cnt].cs_bitmask;
@@ -510,9 +533,11 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_
 				DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
 						  ("cl_value 0x%x cwl_val 0x%x\n",
 						   cl_value, cwl_val));
-				t_wr = TIME_2_CLOCK_CYCLES(speed_bin_table(speed_bin_index,
-									   SPEED_BIN_TWR),
-							   t_ckclk);
+
+				t_wr = time_to_nclk(speed_bin_table
+							   (speed_bin_index,
+							    SPEED_BIN_TWR), t_ckclk);
+
 				data_value =
 					((cl_mask_table[cl_value] & 0x1) << 2) |
 					((cl_mask_table[cl_value] & 0xe) << 3);
@@ -522,9 +547,8 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_
 					      (0x7 << 4) | (1 << 2)));
 				CHECK_STATUS(ddr3_tip_if_write
 					     (dev_num, access_type, if_id,
-					      MR0_REG, twr_mask_table[t_wr + 1] << 9,
-					      (0x7 << 9)));
-
+					      MR0_REG, twr_mask_table[t_wr] << 9,
+					      0x7 << 9));
 
 				/*
 				 * MR1: Set RTT and DIC Design GL values
@@ -545,7 +569,8 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_
 				data_value |=
 					((tm->interface_params[if_id].
 					  interface_temp ==
-					  HWS_TEMP_HIGH) ? (1 << 7) : 0);
+					  MV_DDR_TEMP_HIGH) ? (1 << 7) : 0);
+				data_value |= g_rtt_wr;
 				CHECK_STATUS(ddr3_tip_if_write
 					     (dev_num, access_type, if_id,
 					      MR2_REG, data_value,
@@ -557,53 +582,41 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_
 					   cl_value, cwl_val);
 			ddr3_tip_set_timing(dev_num, access_type, if_id, freq);
 
-			CHECK_STATUS(ddr3_tip_if_write
-				     (dev_num, access_type, if_id,
-				      DUNIT_CONTROL_HIGH_REG, 0x177,
-				      0x1000177));
-
-			if (init_cntr_prm->is_ctrl64_bit) {
-				/* disable 0.25 cc delay */
+			if (ddr3_tip_dev_attr_get(dev_num, MV_ATTR_TIP_REV) < MV_TIP_REV_3) {
+				CHECK_STATUS(ddr3_tip_if_write
+					     (dev_num, access_type, if_id,
+					      DUNIT_CTRL_HIGH_REG, 0x1000119,
+					      0x100017F));
+			} else {
 				CHECK_STATUS(ddr3_tip_if_write
 					     (dev_num, access_type, if_id,
-					      DUNIT_CONTROL_HIGH_REG, 0x0,
-					      0x800));
+					      DUNIT_CTRL_HIGH_REG, 0x600177 |
+					      (init_cntr_prm->is_ctrl64_bit ?
+					      CPU_INTERJECTION_ENA_SPLIT_ENA << CPU_INTERJECTION_ENA_OFFS :
+					      CPU_INTERJECTION_ENA_SPLIT_DIS << CPU_INTERJECTION_ENA_OFFS),
+					      0x1600177 | CPU_INTERJECTION_ENA_MASK <<
+					      CPU_INTERJECTION_ENA_OFFS));
 			}
 
 			/* reset bit 7 */
 			CHECK_STATUS(ddr3_tip_if_write
 				     (dev_num, access_type, if_id,
-				      DUNIT_CONTROL_HIGH_REG,
+				      DUNIT_CTRL_HIGH_REG,
 				      (init_cntr_prm->msys_init << 7), (1 << 7)));
 
-			/* calculate number of CS (per interface) */
-			CHECK_STATUS(calc_cs_num
-				     (dev_num, if_id, &cs_num));
-			timing = tm->interface_params[if_id].timing;
-
-			if (mode2_t != 0xff) {
-				t2t = mode2_t;
-			} else if (timing != HWS_TIM_DEFAULT) {
-				/* Board topology map is forcing timing */
-				t2t = (timing == HWS_TIM_2T) ? 1 : 0;
+			if (mode_2t != 0xff) {
+				t2t = mode_2t;
 			} else {
+				/* calculate number of CS (per interface) */
+				CHECK_STATUS(calc_cs_num
+					     (dev_num, if_id, &cs_num));
 				t2t = (cs_num == 1) ? 0 : 1;
 			}
 
 			CHECK_STATUS(ddr3_tip_if_write
 				     (dev_num, access_type, if_id,
-				      DDR_CONTROL_LOW_REG, t2t << 3,
+				      DUNIT_CTRL_LOW_REG, t2t << 3,
 				      0x3 << 3));
-			/* move the block to ddr3_tip_set_timing - start */
-			t_pd = TIMES_9_TREFI_CYCLES;
-			txpdll = GET_MAX_VALUE(t_ckclk * 10,
-					       speed_bin_table(speed_bin_index,
-							       SPEED_BIN_TXPDLL));
-			txpdll = CEIL_DIVIDE((txpdll - 1), t_ckclk);
-			CHECK_STATUS(ddr3_tip_if_write
-				     (dev_num, access_type, if_id,
-				      DDR_TIMING_REG, txpdll << 4 | t_pd,
-				      0x1f << 4 | 0xf));
 			CHECK_STATUS(ddr3_tip_if_write
 				     (dev_num, access_type, if_id,
 				      DDR_TIMING_REG, 0x28 << 9, 0x3f << 9));
@@ -615,31 +628,38 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_
 			/* AUTO_ZQC_TIMING */
 			CHECK_STATUS(ddr3_tip_if_write
 				     (dev_num, access_type, if_id,
-				      TIMING_REG, (AUTO_ZQC_TIMING | (2 << 20)),
+				      ZQC_CFG_REG, (AUTO_ZQC_TIMING | (2 << 20)),
 				      0x3fffff));
 			CHECK_STATUS(ddr3_tip_if_read
 				     (dev_num, access_type, if_id,
-				      DRAM_PHY_CONFIGURATION, data_read, 0x30));
+				      DRAM_PHY_CFG_REG, data_read, 0x30));
 			data_value =
 				(data_read[if_id] == 0) ? (1 << 11) : 0;
 			CHECK_STATUS(ddr3_tip_if_write
 				     (dev_num, access_type, if_id,
-				      DUNIT_CONTROL_HIGH_REG, data_value,
+				      DUNIT_CTRL_HIGH_REG, data_value,
 				      (1 << 11)));
 
 			/* Set Active control for ODT write transactions */
-			if (cs_num == 1)
-				odt_config = g_odt_config_1cs;
 			CHECK_STATUS(ddr3_tip_if_write
 				     (dev_num, ACCESS_TYPE_MULTICAST,
-				      PARAM_NOT_CARE, 0x1494, odt_config,
+				      PARAM_NOT_CARE, 0x1494, g_odt_config,
 				      MASK_ALL_BITS));
+
+			if (ddr3_tip_dev_attr_get(dev_num, MV_ATTR_TIP_REV) == MV_TIP_REV_3) {
+				CHECK_STATUS(ddr3_tip_if_write
+					     (dev_num, access_type, if_id,
+					      0x14a8, 0x900, 0x900));
+				/* wa: controls control sub-phy outputs floating during self-refresh */
+				CHECK_STATUS(ddr3_tip_if_write
+					     (dev_num, access_type, if_id,
+					      0x16d0, 0, 0x8000));
+			}
 		}
-	} else {
 	}
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		CHECK_STATUS(ddr3_tip_rank_control(dev_num, if_id));
 
 		if (init_cntr_prm->do_mrs_phy) {
@@ -649,14 +669,13 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_
 		/* Pad calibration control - disable */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, access_type, if_id,
-			      CALIB_MACHINE_CTRL_REG, 0x0, 0x1));
+			      MAIN_PADS_CAL_MACH_CTRL_REG, 0x0, 0x1));
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, access_type, if_id,
-			      CALIB_MACHINE_CTRL_REG,
+			      MAIN_PADS_CAL_MACH_CTRL_REG,
 			      calibration_update_control << 3, 0x3 << 3));
 	}
 
-	CHECK_STATUS(ddr3_tip_enable_init_sequence(dev_num));
 
 	if (delay_enable != 0) {
 		adll_tap = MEGA / (freq_val[freq] * 64);
@@ -667,67 +686,70 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_
 }
 
 /*
- * Load Topology map
+ * Rank Control Flow
  */
-int hws_ddr3_tip_load_topology_map(u32 dev_num, struct hws_topology_map *tm)
+static int ddr3_tip_rev2_rank_control(u32 dev_num, u32 if_id)
 {
-	enum hws_speed_bin speed_bin_index;
-	enum hws_ddr_freq freq = DDR_FREQ_LIMIT;
-	u32 if_id;
+	u32 data_value = 0,  bus_cnt = 0;
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
-	freq_val[DDR_FREQ_LOW_FREQ] = dfs_low_freq;
-	tm = ddr3_get_topology_map();
-	CHECK_STATUS(ddr3_tip_get_first_active_if
-		     ((u8)dev_num, tm->if_act_mask,
-		      &first_active_if));
-	DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
-			  ("board IF_Mask=0x%x num_of_bus_per_interface=0x%x\n",
-			   tm->if_act_mask,
-			   tm->num_of_bus_per_interface));
+	for (bus_cnt = 0; bus_cnt < octets_per_if_num; bus_cnt++) {
+		VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_cnt);
+		data_value |= tm->interface_params[if_id].as_bus_params[bus_cnt].
+			      cs_bitmask;
 
-	/*
-	 * if CL, CWL values are missing in topology map, then fill them
-	 * according to speedbin tables
-	 */
-	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-		speed_bin_index =
-			tm->interface_params[if_id].speed_bin_index;
-		/* TBD memory frequency of interface 0 only is used ! */
-		freq = tm->interface_params[first_active_if].memory_freq;
+		if (tm->interface_params[if_id].as_bus_params[bus_cnt].
+		    mirror_enable_bitmask == 1) {
+			/*
+			 * Check mirror_enable_bitmask
+			 * If it is enabled, CS + 4 bit in a word to be '1'
+			 */
+			if ((tm->interface_params[if_id].as_bus_params[bus_cnt].
+			     cs_bitmask & 0x1) != 0) {
+				data_value |= tm->interface_params[if_id].
+					      as_bus_params[bus_cnt].
+					      mirror_enable_bitmask << 4;
+			}
 
-		DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
-				  ("speed_bin_index =%d freq=%d cl=%d cwl=%d\n",
-				   speed_bin_index, freq_val[freq],
-				   tm->interface_params[if_id].
-				   cas_l,
-				   tm->interface_params[if_id].
-				   cas_wl));
+			if ((tm->interface_params[if_id].as_bus_params[bus_cnt].
+			     cs_bitmask & 0x2) != 0) {
+				data_value |= tm->interface_params[if_id].
+					      as_bus_params[bus_cnt].
+					      mirror_enable_bitmask << 5;
+			}
 
-		if (tm->interface_params[if_id].cas_l == 0) {
-			tm->interface_params[if_id].cas_l =
-				cas_latency_table[speed_bin_index].cl_val[freq];
-		}
+			if ((tm->interface_params[if_id].as_bus_params[bus_cnt].
+			     cs_bitmask & 0x4) != 0) {
+				data_value |= tm->interface_params[if_id].
+					      as_bus_params[bus_cnt].
+					      mirror_enable_bitmask << 6;
+			}
 
-		if (tm->interface_params[if_id].cas_wl == 0) {
-			tm->interface_params[if_id].cas_wl =
-				cas_write_latency_table[speed_bin_index].cl_val[freq];
+			if ((tm->interface_params[if_id].as_bus_params[bus_cnt].
+			     cs_bitmask & 0x8) != 0) {
+				data_value |= tm->interface_params[if_id].
+					      as_bus_params[bus_cnt].
+					      mirror_enable_bitmask << 7;
+			}
 		}
 	}
 
+	CHECK_STATUS(ddr3_tip_if_write
+		     (dev_num, ACCESS_TYPE_UNICAST, if_id, DDR3_RANK_CTRL_REG,
+		      data_value, 0xff));
+
 	return MV_OK;
 }
 
-/*
- * RANK Control Flow
- */
-static int ddr3_tip_rank_control(u32 dev_num, u32 if_id)
+static int ddr3_tip_rev3_rank_control(u32 dev_num, u32 if_id)
 {
 	u32 data_value = 0, bus_cnt;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
-	for (bus_cnt = 1; bus_cnt < GET_TOPOLOGY_NUM_OF_BUSES(); bus_cnt++) {
-		VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
+	for (bus_cnt = 1; bus_cnt < octets_per_if_num; bus_cnt++) {
+		VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_cnt);
 		if ((tm->interface_params[if_id].
 		     as_bus_params[0].cs_bitmask !=
 		     tm->interface_params[if_id].
@@ -747,29 +769,38 @@ static int ddr3_tip_rank_control(u32 dev_num, u32 if_id)
 		as_bus_params[0].mirror_enable_bitmask << 4;
 
 	CHECK_STATUS(ddr3_tip_if_write
-		     (dev_num, ACCESS_TYPE_UNICAST, if_id, RANK_CTRL_REG,
+		     (dev_num, ACCESS_TYPE_UNICAST, if_id, DDR3_RANK_CTRL_REG,
 		      data_value, 0xff));
 
 	return MV_OK;
 }
 
+static int ddr3_tip_rank_control(u32 dev_num, u32 if_id)
+{
+	if (ddr3_tip_dev_attr_get(dev_num, MV_ATTR_TIP_REV) == MV_TIP_REV_2)
+		return ddr3_tip_rev2_rank_control(dev_num, if_id);
+	else
+		return ddr3_tip_rev3_rank_control(dev_num, if_id);
+}
+
 /*
  * PAD Inverse Flow
  */
 static int ddr3_tip_pad_inv(u32 dev_num, u32 if_id)
 {
 	u32 bus_cnt, data_value, ck_swap_pup_ctrl;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
-	for (bus_cnt = 0; bus_cnt < GET_TOPOLOGY_NUM_OF_BUSES(); bus_cnt++) {
-		VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
+	for (bus_cnt = 0; bus_cnt < octets_per_if_num; bus_cnt++) {
+		VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_cnt);
 		if (tm->interface_params[if_id].
 		    as_bus_params[bus_cnt].is_dqs_swap == 1) {
 			/* dqs swap */
 			ddr3_tip_bus_read_modify_write(dev_num, ACCESS_TYPE_UNICAST,
 						       if_id, bus_cnt,
 						       DDR_PHY_DATA,
-						       PHY_CONTROL_PHY_REG, 0xc0,
+						       PHY_CTRL_PHY_REG, 0xc0,
 						       0xc0);
 		}
 
@@ -786,7 +817,7 @@ static int ddr3_tip_pad_inv(u32 dev_num, u32 if_id)
 			ddr3_tip_bus_read_modify_write(dev_num, ACCESS_TYPE_UNICAST,
 						       if_id, ck_swap_pup_ctrl,
 						       DDR_PHY_CONTROL,
-						       PHY_CONTROL_PHY_REG,
+						       PHY_CTRL_PHY_REG,
 						       data_value, data_value);
 		}
 	}
@@ -794,12 +825,147 @@ static int ddr3_tip_pad_inv(u32 dev_num, u32 if_id)
 	return MV_OK;
 }
 
+/*
+ * Algorithm Parameters Validation
+ */
+int ddr3_tip_validate_algo_var(u32 value, u32 fail_value, char *var_name)
+{
+	if (value == fail_value) {
+		DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+				  ("Error: %s is not initialized (Algo Components Validation)\n",
+				   var_name));
+		return 0;
+	}
+
+	return 1;
+}
+
+int ddr3_tip_validate_algo_ptr(void *ptr, void *fail_value, char *ptr_name)
+{
+	if (ptr == fail_value) {
+		DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+				  ("Error: %s is not initialized (Algo Components Validation)\n",
+				   ptr_name));
+		return 0;
+	}
+
+	return 1;
+}
+
+int ddr3_tip_validate_algo_components(u8 dev_num)
+{
+	int status = 1;
+
+	/* Check DGL parameters*/
+	status &= ddr3_tip_validate_algo_var(ck_delay, PARAM_UNDEFINED, "ck_delay");
+	status &= ddr3_tip_validate_algo_var(phy_reg3_val, PARAM_UNDEFINED, "phy_reg3_val");
+	status &= ddr3_tip_validate_algo_var(g_rtt_nom, PARAM_UNDEFINED, "g_rtt_nom");
+	status &= ddr3_tip_validate_algo_var(g_dic, PARAM_UNDEFINED, "g_dic");
+	status &= ddr3_tip_validate_algo_var(odt_config, PARAM_UNDEFINED, "odt_config");
+	status &= ddr3_tip_validate_algo_var(g_zpri_data, PARAM_UNDEFINED, "g_zpri_data");
+	status &= ddr3_tip_validate_algo_var(g_znri_data, PARAM_UNDEFINED, "g_znri_data");
+	status &= ddr3_tip_validate_algo_var(g_zpri_ctrl, PARAM_UNDEFINED, "g_zpri_ctrl");
+	status &= ddr3_tip_validate_algo_var(g_znri_ctrl, PARAM_UNDEFINED, "g_znri_ctrl");
+	status &= ddr3_tip_validate_algo_var(g_zpodt_data, PARAM_UNDEFINED, "g_zpodt_data");
+	status &= ddr3_tip_validate_algo_var(g_znodt_data, PARAM_UNDEFINED, "g_znodt_data");
+	status &= ddr3_tip_validate_algo_var(g_zpodt_ctrl, PARAM_UNDEFINED, "g_zpodt_ctrl");
+	status &= ddr3_tip_validate_algo_var(g_znodt_ctrl, PARAM_UNDEFINED, "g_znodt_ctrl");
+
+	/* Check functions pointers */
+	status &= ddr3_tip_validate_algo_ptr(config_func_info[dev_num].tip_dunit_mux_select_func,
+					     NULL, "tip_dunit_mux_select_func");
+	status &= ddr3_tip_validate_algo_ptr(config_func_info[dev_num].mv_ddr_dunit_write,
+					     NULL, "mv_ddr_dunit_write");
+	status &= ddr3_tip_validate_algo_ptr(config_func_info[dev_num].mv_ddr_dunit_read,
+					     NULL, "mv_ddr_dunit_read");
+	status &= ddr3_tip_validate_algo_ptr(config_func_info[dev_num].mv_ddr_phy_write,
+					     NULL, "mv_ddr_phy_write");
+	status &= ddr3_tip_validate_algo_ptr(config_func_info[dev_num].mv_ddr_phy_read,
+					     NULL, "mv_ddr_phy_read");
+	status &= ddr3_tip_validate_algo_ptr(config_func_info[dev_num].tip_get_freq_config_info_func,
+					     NULL, "tip_get_freq_config_info_func");
+	status &= ddr3_tip_validate_algo_ptr(config_func_info[dev_num].tip_set_freq_divider_func,
+					     NULL, "tip_set_freq_divider_func");
+	status &= ddr3_tip_validate_algo_ptr(config_func_info[dev_num].tip_get_clock_ratio,
+					     NULL, "tip_get_clock_ratio");
+
+	status &= ddr3_tip_validate_algo_ptr(dq_map_table, NULL, "dq_map_table");
+	status &= ddr3_tip_validate_algo_var(dfs_low_freq, 0, "dfs_low_freq");
+
+	return (status == 1) ? MV_OK : MV_NOT_INITIALIZED;
+}
+
+
+int ddr3_pre_algo_config(void)
+{
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+
+	/* Set Bus3 ECC training mode */
+	if (DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask)) {
+		/* Set Bus3 ECC MUX */
+		CHECK_STATUS(ddr3_tip_if_write
+			     (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE,
+			      DRAM_PINS_MUX_REG, 0x100, 0x100));
+	}
+
+	/* Set regular ECC training mode (bus4 and bus 3) */
+	if ((DDR3_IS_ECC_PUP4_MODE(tm->bus_act_mask)) ||
+	    (DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask)) ||
+	    (DDR3_IS_ECC_PUP8_MODE(tm->bus_act_mask))) {
+		/* Enable ECC Write MUX */
+		CHECK_STATUS(ddr3_tip_if_write
+			     (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE,
+			      TRAINING_SW_2_REG, 0x100, 0x100));
+		/* General ECC enable */
+		CHECK_STATUS(ddr3_tip_if_write
+			     (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE,
+			      SDRAM_CFG_REG, 0x40000, 0x40000));
+		/* Disable Read Data ECC MUX */
+		CHECK_STATUS(ddr3_tip_if_write
+			     (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE,
+			      TRAINING_SW_2_REG, 0x0, 0x2));
+	}
+
+	return MV_OK;
+}
+
+int ddr3_post_algo_config(void)
+{
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+	int status;
+
+	status = ddr3_post_run_alg();
+	if (MV_OK != status) {
+		printf("DDR3 Post Run Alg - FAILED 0x%x\n", status);
+		return status;
+	}
+
+	/* Un_set ECC training mode */
+	if ((DDR3_IS_ECC_PUP4_MODE(tm->bus_act_mask)) ||
+	    (DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask)) ||
+	    (DDR3_IS_ECC_PUP8_MODE(tm->bus_act_mask))) {
+		/* Disable ECC Write MUX */
+		CHECK_STATUS(ddr3_tip_if_write
+			     (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE,
+			      TRAINING_SW_2_REG, 0x0, 0x100));
+		/* General ECC and Bus3 ECC MUX remains enabled */
+	}
+
+	return MV_OK;
+}
+
 /*
  * Run Training Flow
  */
 int hws_ddr3_tip_run_alg(u32 dev_num, enum hws_algo_type algo_type)
 {
-	int ret = MV_OK, ret_tune = MV_OK;
+	int status = MV_OK;
+
+	status = ddr3_pre_algo_config();
+	if (MV_OK != status) {
+		printf("DDR3 Pre Algo Config - FAILED 0x%x\n", status);
+		return status;
+	}
 
 #ifdef ODT_TEST_SUPPORT
 	if (finger_test == 1)
@@ -807,16 +973,23 @@ int hws_ddr3_tip_run_alg(u32 dev_num, enum hws_algo_type algo_type)
 #endif
 
 	if (algo_type == ALGO_TYPE_DYNAMIC) {
-		ret = ddr3_tip_ddr3_auto_tune(dev_num);
-	} else {
+		status = ddr3_tip_ddr3_auto_tune(dev_num);
 	}
 
-	if (ret != MV_OK) {
+	if (status != MV_OK) {
 		DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
-				  ("Run_alg: tuning failed %d\n", ret_tune));
+				  ("********   DRAM initialization Failed (res 0x%x)   ********\n",
+				   status));
+		return status;
 	}
 
-	return ret;
+	status = ddr3_post_algo_config();
+	if (MV_OK != status) {
+		printf("DDR3 Post Algo Config - FAILED 0x%x\n", status);
+		return status;
+	}
+
+	return status;
 }
 
 #ifdef ODT_TEST_SUPPORT
@@ -836,19 +1009,16 @@ static int odt_test(u32 dev_num, enum hws_algo_type algo_type)
 				DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
 						  ("pfinger_val %d nfinger_val %d\n",
 						   pfinger_val, nfinger_val));
-				p_finger = pfinger_val;
-				n_finger = nfinger_val;
+				/*
+				 * TODO: need to check the correctness
+				 * of the following two lines.
+				 */
+				g_zpodt_data = pfinger_val;
+				g_znodt_data = nfinger_val;
 			}
 
 			if (algo_type == ALGO_TYPE_DYNAMIC) {
 				ret = ddr3_tip_ddr3_auto_tune(dev_num);
-			} else {
-				/*
-				 * Frequency per interface is not relevant,
-				 * only interface 0
-				 */
-				ret = ddr3_tip_run_static_alg(dev_num,
-							      init_freq);
 			}
 		}
 	}
@@ -868,12 +1038,8 @@ static int odt_test(u32 dev_num, enum hws_algo_type algo_type)
  */
 int hws_ddr3_tip_select_ddr_controller(u32 dev_num, int enable)
 {
-	if (config_func_info[dev_num].tip_dunit_mux_select_func != NULL) {
-		return config_func_info[dev_num].
-			tip_dunit_mux_select_func((u8)dev_num, enable);
-	}
-
-	return MV_FAIL;
+	return config_func_info[dev_num].
+		tip_dunit_mux_select_func((u8)dev_num, enable);
 }
 
 /*
@@ -882,14 +1048,9 @@ int hws_ddr3_tip_select_ddr_controller(u32 dev_num, int enable)
 int ddr3_tip_if_write(u32 dev_num, enum hws_access_type interface_access,
 		      u32 if_id, u32 reg_addr, u32 data_value, u32 mask)
 {
-	if (config_func_info[dev_num].tip_dunit_write_func != NULL) {
-		return config_func_info[dev_num].
-			tip_dunit_write_func((u8)dev_num, interface_access,
-					     if_id, reg_addr,
-					     data_value, mask);
-	}
+	config_func_info[dev_num].mv_ddr_dunit_write(reg_addr, mask, data_value);
 
-	return MV_FAIL;
+	return MV_OK;
 }
 
 /*
@@ -898,14 +1059,9 @@ int ddr3_tip_if_write(u32 dev_num, enum hws_access_type interface_access,
 int ddr3_tip_if_read(u32 dev_num, enum hws_access_type interface_access,
 		     u32 if_id, u32 reg_addr, u32 *data, u32 mask)
 {
-	if (config_func_info[dev_num].tip_dunit_read_func != NULL) {
-		return config_func_info[dev_num].
-			tip_dunit_read_func((u8)dev_num, interface_access,
-					    if_id, reg_addr,
-					    data, mask);
-	}
+	config_func_info[dev_num].mv_ddr_dunit_read(reg_addr, mask, data);
 
-	return MV_FAIL;
+	return MV_OK;
 }
 
 /*
@@ -919,7 +1075,7 @@ int ddr3_tip_if_polling(u32 dev_num, enum hws_access_type access_type,
 	u32 read_data[MAX_INTERFACE_NUM];
 	int ret;
 	int is_fail = 0, is_if_fail;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	if (access_type == ACCESS_TYPE_MULTICAST) {
 		start_if = 0;
@@ -931,7 +1087,7 @@ int ddr3_tip_if_polling(u32 dev_num, enum hws_access_type access_type,
 
 	for (interface_num = start_if; interface_num <= end_if; interface_num++) {
 		/* polling bit 3 for n times */
-		VALIDATE_ACTIVE(tm->if_act_mask, interface_num);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, interface_num);
 
 		is_if_fail = 0;
 		for (poll_cnt = 0; poll_cnt < poll_tries; poll_cnt++) {
@@ -967,42 +1123,8 @@ int ddr3_tip_bus_read(u32 dev_num, u32 if_id,
 		      enum hws_access_type phy_access, u32 phy_id,
 		      enum hws_ddr_phy phy_type, u32 reg_addr, u32 *data)
 {
-	u32 bus_index = 0;
-	u32 data_read[MAX_INTERFACE_NUM];
-	struct hws_topology_map *tm = ddr3_get_topology_map();
-
-	if (phy_access == ACCESS_TYPE_MULTICAST) {
-		for (bus_index = 0; bus_index < GET_TOPOLOGY_NUM_OF_BUSES();
-		     bus_index++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, bus_index);
-			CHECK_STATUS(ddr3_tip_bus_access
-				     (dev_num, ACCESS_TYPE_UNICAST,
-				      if_id, ACCESS_TYPE_UNICAST,
-				      bus_index, phy_type, reg_addr, 0,
-				      OPERATION_READ));
-			CHECK_STATUS(ddr3_tip_if_read
-				     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-				      PHY_REG_FILE_ACCESS, data_read,
-				      MASK_ALL_BITS));
-			data[bus_index] = (data_read[if_id] & 0xffff);
-		}
-	} else {
-		CHECK_STATUS(ddr3_tip_bus_access
-			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      phy_access, phy_id, phy_type, reg_addr, 0,
-			      OPERATION_READ));
-		CHECK_STATUS(ddr3_tip_if_read
-			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      PHY_REG_FILE_ACCESS, data_read, MASK_ALL_BITS));
-
-		/*
-		 * only 16 lsb bit are valid in Phy (each register is different,
-		 * some can actually be less than 16 bits)
-		 */
-		*data = (data_read[if_id] & 0xffff);
-	}
-
-	return MV_OK;
+	return config_func_info[dev_num].
+		mv_ddr_phy_read(phy_access, phy_id, phy_type, reg_addr, data);
 }
 
 /*
@@ -1013,88 +1135,10 @@ int ddr3_tip_bus_write(u32 dev_num, enum hws_access_type interface_access,
 		       u32 phy_id, enum hws_ddr_phy phy_type, u32 reg_addr,
 		       u32 data_value)
 {
-	CHECK_STATUS(ddr3_tip_bus_access
-		     (dev_num, interface_access, if_id, phy_access,
-		      phy_id, phy_type, reg_addr, data_value, OPERATION_WRITE));
-
-	return MV_OK;
-}
-
-/*
- * Bus access routine (relevant for both read & write)
- */
-static int ddr3_tip_bus_access(u32 dev_num, enum hws_access_type interface_access,
-			       u32 if_id, enum hws_access_type phy_access,
-			       u32 phy_id, enum hws_ddr_phy phy_type, u32 reg_addr,
-			       u32 data_value, enum hws_operation oper_type)
-{
-	u32 addr_low = 0x3f & reg_addr;
-	u32 addr_hi = ((0xc0 & reg_addr) >> 6);
-	u32 data_p1 =
-		(oper_type << 30) + (addr_hi << 28) + (phy_access << 27) +
-		(phy_type << 26) + (phy_id << 22) + (addr_low << 16) +
-		(data_value & 0xffff);
-	u32 data_p2 = data_p1 + (1 << 31);
-	u32 start_if, end_if;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
-
-	CHECK_STATUS(ddr3_tip_if_write
-		     (dev_num, interface_access, if_id, PHY_REG_FILE_ACCESS,
-		      data_p1, MASK_ALL_BITS));
-	CHECK_STATUS(ddr3_tip_if_write
-		     (dev_num, interface_access, if_id, PHY_REG_FILE_ACCESS,
-		      data_p2, MASK_ALL_BITS));
-
-	if (interface_access == ACCESS_TYPE_UNICAST) {
-		start_if = if_id;
-		end_if = if_id;
-	} else {
-		start_if = 0;
-		end_if = MAX_INTERFACE_NUM - 1;
-	}
-
-	/* polling for read/write execution done */
-	for (if_id = start_if; if_id <= end_if; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-		CHECK_STATUS(is_bus_access_done
-			     (dev_num, if_id, PHY_REG_FILE_ACCESS, 31));
-	}
-
-	return MV_OK;
+	return config_func_info[dev_num].
+		mv_ddr_phy_write(phy_access, phy_id, phy_type, reg_addr, data_value, OPERATION_WRITE);
 }
 
-/*
- * Check bus access done
- */
-static int is_bus_access_done(u32 dev_num, u32 if_id, u32 dunit_reg_adrr,
-			      u32 bit)
-{
-	u32 rd_data = 1;
-	u32 cnt = 0;
-	u32 data_read[MAX_INTERFACE_NUM];
-
-	CHECK_STATUS(ddr3_tip_if_read
-		     (dev_num, ACCESS_TYPE_UNICAST, if_id, dunit_reg_adrr,
-		      data_read, MASK_ALL_BITS));
-	rd_data = data_read[if_id];
-	rd_data &= (1 << bit);
-
-	while (rd_data != 0) {
-		if (cnt++ >= MAX_POLLING_ITERATIONS)
-			break;
-
-		CHECK_STATUS(ddr3_tip_if_read
-			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      dunit_reg_adrr, data_read, MASK_ALL_BITS));
-		rd_data = data_read[if_id];
-		rd_data &= (1 << bit);
-	}
-
-	if (cnt < MAX_POLLING_ITERATIONS)
-		return MV_OK;
-	else
-		return MV_FAIL;
-}
 
 /*
  * Phy read-modify-write
@@ -1105,7 +1149,7 @@ int ddr3_tip_bus_read_modify_write(u32 dev_num, enum hws_access_type access_type
 				   u32 data_value, u32 reg_mask)
 {
 	u32 data_val = 0, if_id, start_if, end_if;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	if (access_type == ACCESS_TYPE_MULTICAST) {
 		start_if = 0;
@@ -1116,7 +1160,7 @@ int ddr3_tip_bus_read_modify_write(u32 dev_num, enum hws_access_type access_type
 	}
 
 	for (if_id = start_if; if_id <= end_if; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		CHECK_STATUS(ddr3_tip_bus_read
 			     (dev_num, if_id, ACCESS_TYPE_UNICAST, phy_id,
 			      phy_type, reg_addr, &data_val));
@@ -1138,46 +1182,52 @@ int adll_calibration(u32 dev_num, enum hws_access_type access_type,
 {
 	struct hws_tip_freq_config_info freq_config_info;
 	u32 bus_cnt = 0;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	/* Reset Diver_b assert -> de-assert */
 	CHECK_STATUS(ddr3_tip_if_write
-		     (dev_num, access_type, if_id, SDRAM_CONFIGURATION_REG,
+		     (dev_num, access_type, if_id, SDRAM_CFG_REG,
 		      0, 0x10000000));
 	mdelay(10);
 	CHECK_STATUS(ddr3_tip_if_write
-		     (dev_num, access_type, if_id, SDRAM_CONFIGURATION_REG,
+		     (dev_num, access_type, if_id, SDRAM_CFG_REG,
 		      0x10000000, 0x10000000));
 
-	if (config_func_info[dev_num].tip_get_freq_config_info_func != NULL) {
-		CHECK_STATUS(config_func_info[dev_num].
-			     tip_get_freq_config_info_func((u8)dev_num, frequency,
-							   &freq_config_info));
-	} else {
-		DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
-				  ("tip_get_freq_config_info_func is NULL"));
-		return MV_NOT_INITIALIZED;
-	}
+	CHECK_STATUS(config_func_info[dev_num].
+		     tip_get_freq_config_info_func((u8)dev_num, frequency,
+						   &freq_config_info));
 
-	for (bus_cnt = 0; bus_cnt < GET_TOPOLOGY_NUM_OF_BUSES(); bus_cnt++) {
-		VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
+	for (bus_cnt = 0; bus_cnt < octets_per_if_num; bus_cnt++) {
+		VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_cnt);
 		CHECK_STATUS(ddr3_tip_bus_read_modify_write
 			     (dev_num, access_type, if_id, bus_cnt,
-			      DDR_PHY_DATA, BW_PHY_REG,
+			      DDR_PHY_DATA, ADLL_CFG0_PHY_REG,
 			      freq_config_info.bw_per_freq << 8, 0x700));
 		CHECK_STATUS(ddr3_tip_bus_read_modify_write
 			     (dev_num, access_type, if_id, bus_cnt,
-			      DDR_PHY_DATA, RATE_PHY_REG,
+			      DDR_PHY_DATA, ADLL_CFG2_PHY_REG,
+			      freq_config_info.rate_per_freq, 0x7));
+	}
+
+	for (bus_cnt = 0; bus_cnt < DDR_IF_CTRL_SUBPHYS_NUM; bus_cnt++) {
+		CHECK_STATUS(ddr3_tip_bus_read_modify_write
+			     (dev_num, ACCESS_TYPE_UNICAST, if_id, bus_cnt,
+			      DDR_PHY_CONTROL, ADLL_CFG0_PHY_REG,
+			      freq_config_info.bw_per_freq << 8, 0x700));
+		CHECK_STATUS(ddr3_tip_bus_read_modify_write
+			     (dev_num, ACCESS_TYPE_UNICAST, if_id, bus_cnt,
+			      DDR_PHY_CONTROL, ADLL_CFG2_PHY_REG,
 			      freq_config_info.rate_per_freq, 0x7));
 	}
 
 	/* DUnit to Phy drive post edge, ADLL reset assert de-assert */
 	CHECK_STATUS(ddr3_tip_if_write
-		     (dev_num, access_type, if_id, DRAM_PHY_CONFIGURATION,
+		     (dev_num, access_type, if_id, DRAM_PHY_CFG_REG,
 		      0, (0x80000000 | 0x40000000)));
 	mdelay(100 / (freq_val[frequency] / freq_val[DDR_FREQ_LOW_FREQ]));
 	CHECK_STATUS(ddr3_tip_if_write
-		     (dev_num, access_type, if_id, DRAM_PHY_CONFIGURATION,
+		     (dev_num, access_type, if_id, DRAM_PHY_CFG_REG,
 		      (0x80000000 | 0x40000000), (0x80000000 | 0x40000000)));
 
 	/* polling for ADLL Done */
@@ -1190,11 +1240,11 @@ int adll_calibration(u32 dev_num, enum hws_access_type access_type,
 
 	/* pup data_pup reset assert-> deassert */
 	CHECK_STATUS(ddr3_tip_if_write
-		     (dev_num, access_type, if_id, SDRAM_CONFIGURATION_REG,
+		     (dev_num, access_type, if_id, SDRAM_CFG_REG,
 		      0, 0x60000000));
 	mdelay(10);
 	CHECK_STATUS(ddr3_tip_if_write
-		     (dev_num, access_type, if_id, SDRAM_CONFIGURATION_REG,
+		     (dev_num, access_type, if_id, SDRAM_CFG_REG,
 		      0x60000000, 0x60000000));
 
 	return MV_OK;
@@ -1204,18 +1254,21 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type,
 		      u32 if_id, enum hws_ddr_freq frequency)
 {
 	u32 cl_value = 0, cwl_value = 0, mem_mask = 0, val = 0,
-		bus_cnt = 0, t_hclk = 0, t_wr = 0,
-		refresh_interval_cnt = 0, cnt_id;
-	u32 t_ckclk;
-	u32 t_refi = 0, end_if, start_if;
+		bus_cnt = 0, t_wr = 0, t_ckclk = 0,
+		cnt_id;
+	u32 end_if, start_if;
 	u32 bus_index = 0;
 	int is_dll_off = 0;
 	enum hws_speed_bin speed_bin_index = 0;
 	struct hws_tip_freq_config_info freq_config_info;
 	enum hws_result *flow_result = training_result[training_stage];
 	u32 adll_tap = 0;
+	u32 cs_num;
+	u32 t2t;
 	u32 cs_mask[MAX_INTERFACE_NUM];
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+	unsigned int tclk;
 
 	DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
 			  ("dev %d access %d IF %d freq %d\n", dev_num,
@@ -1235,7 +1288,7 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type,
 	/* speed bin can be different for each interface */
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
 		/* cs enable is active low */
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		cs_mask[if_id] = CS_BIT_MASK;
 		training_result[training_stage][if_id] = TEST_SUCCESS;
 		ddr3_tip_calc_cs_mask(dev_num, if_id, effective_cs,
@@ -1248,8 +1301,7 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type,
 	 * and loop the unicast access functions
 	 */
 	for (if_id = start_if; if_id <= end_if; if_id++) {
-		if (IS_ACTIVE(tm->if_act_mask, if_id) == 0)
-			continue;
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 
 		flow_result[if_id] = TEST_SUCCESS;
 		speed_bin_index =
@@ -1260,6 +1312,18 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type,
 				tm->interface_params[if_id].cas_l;
 			cwl_value =
 				tm->interface_params[if_id].cas_wl;
+		} else if (tm->cfg_src == MV_DDR_CFG_SPD) {
+			tclk = 1000000 / freq_val[frequency];
+			cl_value = mv_ddr_cl_calc(tm->timing_data[MV_DDR_TAA_MIN], tclk);
+			if (cl_value == 0) {
+				printf("mv_ddr: unsupported cas latency value found\n");
+				return MV_FAIL;
+			}
+			cwl_value = mv_ddr_cwl_calc(tclk);
+			if (cwl_value == 0) {
+				printf("mv_ddr: unsupported cas write latency value found\n");
+				return MV_FAIL;
+			}
 		} else {
 			cl_value =
 				cas_latency_table[speed_bin_index].cl_val[frequency];
@@ -1273,7 +1337,7 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type,
 				   dev_num, access_type, if_id,
 				   frequency, speed_bin_index));
 
-		for (cnt_id = 0; cnt_id < DDR_FREQ_LIMIT; cnt_id++) {
+		for (cnt_id = 0; cnt_id < DDR_FREQ_LAST; cnt_id++) {
 			DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
 					  ("%d ",
 					   cas_latency_table[speed_bin_index].
@@ -1282,19 +1346,19 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type,
 
 		DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE, ("\n"));
 		mem_mask = 0;
-		for (bus_index = 0; bus_index < GET_TOPOLOGY_NUM_OF_BUSES();
+		for (bus_index = 0; bus_index < octets_per_if_num;
 		     bus_index++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, bus_index);
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_index);
 			mem_mask |=
 				tm->interface_params[if_id].
 				as_bus_params[bus_index].mirror_enable_bitmask;
 		}
 
 		if (mem_mask != 0) {
-			/* motib redundant in KW28 */
+			/* motib redundent in KW28 */
 			CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type,
 						       if_id,
-						       CS_ENABLE_REG, 0, 0x8));
+						       DUAL_DUNIT_CFG_REG, 0, 0x8));
 		}
 
 		/* dll state after exiting SR */
@@ -1344,27 +1408,37 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type,
 					  ("Freq_set: DDR3 poll failed on SR entry\n"));
 		}
 
-		/* PLL configuration */
-		if (config_func_info[dev_num].tip_set_freq_divider_func != NULL) {
-			config_func_info[dev_num].
-				tip_set_freq_divider_func(dev_num, if_id,
-							  frequency);
+		/* Calculate 2T mode */
+		if (mode_2t != 0xff) {
+			t2t = mode_2t;
+		} else {
+			/* Calculate number of CS per interface */
+			CHECK_STATUS(calc_cs_num(dev_num, if_id, &cs_num));
+			t2t = (cs_num == 1) ? 0 : 1;
 		}
 
-		/* PLL configuration End */
 
-		/* adjust t_refi to new frequency */
-		t_refi = (tm->interface_params[if_id].interface_temp ==
-			  HWS_TEMP_HIGH) ? TREFI_HIGH : TREFI_LOW;
-		t_refi *= 1000;	/*psec */
+		if (ddr3_tip_dev_attr_get(dev_num, MV_ATTR_INTERLEAVE_WA) == 1) {
+			/* Use 1T mode if 1:1 ratio configured */
+			if (config_func_info[dev_num].tip_get_clock_ratio(frequency) == 1) {
+				/* Low freq*/
+				CHECK_STATUS(ddr3_tip_if_write
+					     (dev_num, access_type, if_id,
+					      SDRAM_OPEN_PAGES_CTRL_REG, 0x0, 0x3C0));
+				t2t = 0;
+			} else {
+				/* Middle or target freq */
+				CHECK_STATUS(ddr3_tip_if_write
+					     (dev_num, access_type, if_id,
+					      SDRAM_OPEN_PAGES_CTRL_REG, 0x3C0, 0x3C0));
+			}
+		}
+		CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
+					       DUNIT_CTRL_LOW_REG, t2t << 3, 0x3 << 3));
 
-		/* HCLK in[ps] */
-		t_hclk = MEGA / (freq_val[frequency] / 2);
-		refresh_interval_cnt = t_refi / t_hclk;	/* no units */
-		val = 0x4000 | refresh_interval_cnt;
-		CHECK_STATUS(ddr3_tip_if_write
-			     (dev_num, access_type, if_id,
-			      SDRAM_CONFIGURATION_REG, val, 0x7fff));
+		/* PLL configuration */
+		config_func_info[dev_num].tip_set_freq_divider_func(dev_num, if_id,
+								    frequency);
 
 		/* DFS  - CL/CWL/WR parameters after exiting SR */
 		CHECK_STATUS(ddr3_tip_if_write
@@ -1374,14 +1448,14 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type,
 			     (dev_num, access_type, if_id, DFS_REG,
 			      (cwl_mask_table[cwl_value] << 12), 0x7000));
 
-		t_ckclk = MEGA / freq_val[frequency];
-		t_wr = TIME_2_CLOCK_CYCLES(speed_bin_table(speed_bin_index,
-							   SPEED_BIN_TWR),
-					   t_ckclk);
+		t_ckclk = (MEGA / freq_val[frequency]);
+		t_wr = time_to_nclk(speed_bin_table
+					   (speed_bin_index,
+					    SPEED_BIN_TWR), t_ckclk);
 
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, access_type, if_id, DFS_REG,
-			      (twr_mask_table[t_wr + 1] << 16), 0x70000));
+			      (twr_mask_table[t_wr] << 16), 0x70000));
 
 		/* Restore original RTT values if returning from DLL OFF mode */
 		if (is_dll_off == 1) {
@@ -1399,25 +1473,24 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type,
 				      g_dic | g_rtt_nom, 0x266));
 		}
 
-		/* Reset Diver_b assert -> de-assert */
+		/* Reset divider_b assert -> de-assert */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, access_type, if_id,
-			      SDRAM_CONFIGURATION_REG, 0, 0x10000000));
+			      SDRAM_CFG_REG, 0, 0x10000000));
 		mdelay(10);
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, access_type, if_id,
-			      SDRAM_CONFIGURATION_REG, 0x10000000, 0x10000000));
+			      SDRAM_CFG_REG, 0x10000000, 0x10000000));
+
+		/* ADLL configuration function of process and frequency */
+		CHECK_STATUS(config_func_info[dev_num].
+			     tip_get_freq_config_info_func(dev_num, frequency,
+							   &freq_config_info));
 
-		/* Adll configuration function of process and Frequency */
-		if (config_func_info[dev_num].tip_get_freq_config_info_func != NULL) {
-			CHECK_STATUS(config_func_info[dev_num].
-				     tip_get_freq_config_info_func(dev_num, frequency,
-								   &freq_config_info));
-		}
 		/* TBD check milo5 using device ID ? */
-		for (bus_cnt = 0; bus_cnt < GET_TOPOLOGY_NUM_OF_BUSES();
+		for (bus_cnt = 0; bus_cnt < octets_per_if_num;
 		     bus_cnt++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_cnt);
 			CHECK_STATUS(ddr3_tip_bus_read_modify_write
 				     (dev_num, ACCESS_TYPE_UNICAST,
 				      if_id, bus_cnt, DDR_PHY_DATA,
@@ -1432,15 +1505,15 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type,
 				      freq_config_info.rate_per_freq, 0x7));
 		}
 
-		/* DUnit to Phy drive post edge, ADLL reset assert de-assert */
+		/* Dunit to PHY drive post edge, ADLL reset assert -> de-assert */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, access_type, if_id,
-			      DRAM_PHY_CONFIGURATION, 0,
+			      DRAM_PHY_CFG_REG, 0,
 			      (0x80000000 | 0x40000000)));
 		mdelay(100 / (freq_val[frequency] / freq_val[DDR_FREQ_LOW_FREQ]));
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, access_type, if_id,
-			      DRAM_PHY_CONFIGURATION, (0x80000000 | 0x40000000),
+			      DRAM_PHY_CFG_REG, (0x80000000 | 0x40000000),
 			      (0x80000000 | 0x40000000)));
 
 		/* polling for ADLL Done */
@@ -1455,16 +1528,16 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type,
 		/* pup data_pup reset assert-> deassert */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, access_type, if_id,
-			      SDRAM_CONFIGURATION_REG, 0, 0x60000000));
+			      SDRAM_CFG_REG, 0, 0x60000000));
 		mdelay(10);
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, access_type, if_id,
-			      SDRAM_CONFIGURATION_REG, 0x60000000, 0x60000000));
+			      SDRAM_CFG_REG, 0x60000000, 0x60000000));
 
 		/* Set proper timing params before existing Self-Refresh */
 		ddr3_tip_set_timing(dev_num, access_type, if_id, frequency);
 		if (delay_enable != 0) {
-			adll_tap = MEGA / (freq_val[frequency] * 64);
+			adll_tap = (is_dll_off == 1) ? 1000 : (MEGA / (freq_val[frequency] * 64));
 			ddr3_tip_cmd_addr_init_delay(dev_num, adll_tap);
 		}
 
@@ -1482,10 +1555,10 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type,
 		/* Refresh Command */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, access_type, if_id,
-			      SDRAM_OPERATION_REG, 0x2, 0xf1f));
+			      SDRAM_OP_REG, 0x2, 0xf1f));
 		if (ddr3_tip_if_polling
 		    (dev_num, ACCESS_TYPE_UNICAST, if_id, 0, 0x1f,
-		     SDRAM_OPERATION_REG, MAX_POLLING_ITERATIONS) != MV_OK) {
+		     SDRAM_OP_REG, MAX_POLLING_ITERATIONS) != MV_OK) {
 			DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
 					  ("Freq_set: DDR3 poll failed(3)"));
 		}
@@ -1507,54 +1580,57 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type,
 			     (dev_num, access_type, if_id, MR0_REG,
 			      val, (0x7 << 4) | (1 << 2)));
 		/* MR2:  CWL = 10 , Auto Self-Refresh - disable */
-		val = (cwl_mask_table[cwl_value] << 3);
+		val = (cwl_mask_table[cwl_value] << 3) | g_rtt_wr;
 		/*
 		 * nklein 24.10.13 - should not be here - leave value as set in
 		 * the init configuration val |= (1 << 9);
 		 * val |= ((tm->interface_params[if_id].
-		 * interface_temp == HWS_TEMP_HIGH) ? (1 << 7) : 0);
+		 * interface_temp == MV_DDR_TEMP_HIGH) ? (1 << 7) : 0);
 		 */
 		/* nklein 24.10.13 - see above comment */
 		CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type,
 					       if_id, MR2_REG,
-					       val, (0x7 << 3)));
+					       val, (0x7 << 3) | (0x3 << 9)));
 
 		/* ODT TIMING */
 		val = ((cl_value - cwl_value + 1) << 4) |
 			((cl_value - cwl_value + 6) << 8) |
 			((cl_value - 1) << 12) | ((cl_value + 6) << 16);
 		CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type,
-					       if_id, ODT_TIMING_LOW,
+					       if_id, DDR_ODT_TIMING_LOW_REG,
 					       val, 0xffff0));
 		val = 0x91 | ((cwl_value - 1) << 8) | ((cwl_value + 5) << 12);
 		CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type,
-					       if_id, ODT_TIMING_HI_REG,
+					       if_id, DDR_ODT_TIMING_HIGH_REG,
 					       val, 0xffff));
 
-		/* ODT Active */
-		CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type,
-					       if_id,
-					       DUNIT_ODT_CONTROL_REG,
-					       0xf, 0xf));
+		/* in case of ddr4 need to set the receiver to odt always 'on' (odt_config = '0')
+		 * in case of ddr3 configure the odt through the timing
+		 */
+		if (odt_config != 0) {
+			CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id, DUNIT_ODT_CTRL_REG, 0xf, 0xf));
+		}
+		else {
+			CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id, DUNIT_ODT_CTRL_REG,
+						       0x30f, 0x30f));
+		}
 
 		/* re-write CL */
 		val = ((cl_mask_table[cl_value] & 0x1) << 2) |
 			((cl_mask_table[cl_value] & 0xe) << 3);
-		CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
-					       0, MR0_REG, val,
-					       (0x7 << 4) | (1 << 2)));
+
+		CHECK_STATUS(ddr3_tip_write_mrs_cmd(dev_num, cs_mask, MR_CMD0,
+			val, (0x7 << 4) | (0x1 << 2)));
 
 		/* re-write CWL */
-		val = (cwl_mask_table[cwl_value] << 3);
-		CHECK_STATUS(ddr3_tip_write_mrs_cmd(dev_num, cs_mask, MRS2_CMD,
-						    val, (0x7 << 3)));
-		CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
-					       0, MR2_REG, val, (0x7 << 3)));
+		val = (cwl_mask_table[cwl_value] << 3) | g_rtt_wr;
+		CHECK_STATUS(ddr3_tip_write_mrs_cmd(dev_num, cs_mask, MR_CMD2,
+			val, (0x7 << 3) | (0x3 << 9)));
 
 		if (mem_mask != 0) {
 			CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type,
 						       if_id,
-						       CS_ENABLE_REG,
+						       DUAL_DUNIT_CFG_REG,
 						       1 << 3, 0x8));
 		}
 	}
@@ -1577,20 +1653,20 @@ static int ddr3_tip_write_odt(u32 dev_num, enum hws_access_type access_type,
 	val |= (((cl_value - 1) >> 4) << 22) | (((cl_value + 6) >> 4) << 23);
 
 	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
-				       ODT_TIMING_LOW, val, 0xffff0));
+				       DDR_ODT_TIMING_LOW_REG, val, 0xffff0));
 	val = 0x91 | ((cwl_value - 1) << 8) | ((cwl_value + 5) << 12);
 	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
-				       ODT_TIMING_HI_REG, val, 0xffff));
+				       DDR_ODT_TIMING_HIGH_REG, val, 0xffff));
 	if (odt_additional == 1) {
 		CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type,
 					       if_id,
-					       SDRAM_ODT_CONTROL_HIGH_REG,
+					       SDRAM_ODT_CTRL_HIGH_REG,
 					       0xf, 0xf));
 	}
 
 	/* ODT Active */
 	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
-				       DUNIT_ODT_CONTROL_REG, 0xf, 0xf));
+				       DUNIT_ODT_CTRL_REG, 0xf, 0xf));
 
 	return MV_OK;
 }
@@ -1603,88 +1679,146 @@ static int ddr3_tip_set_timing(u32 dev_num, enum hws_access_type access_type,
 {
 	u32 t_ckclk = 0, t_ras = 0;
 	u32 t_rcd = 0, t_rp = 0, t_wr = 0, t_wtr = 0, t_rrd = 0, t_rtp = 0,
-		t_rfc = 0, t_mod = 0;
-	u32 val = 0, page_size = 0;
+		t_rfc = 0, t_mod = 0, t_r2r = 0x3, t_r2r_high = 0,
+		t_r2w_w2r = 0x3, t_r2w_w2r_high = 0x1, t_w2w = 0x3;
+	u32 refresh_interval_cnt, t_hclk, t_refi, t_faw, t_pd, t_xpdll;
+	u32 val = 0, page_size = 0, mask = 0;
 	enum hws_speed_bin speed_bin_index;
-	enum hws_mem_size memory_size = MEM_2G;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	enum mv_ddr_die_capacity memory_size = MV_DDR_DIE_CAP_2GBIT;
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+	struct page_element *page_param = mv_ddr_page_tbl_get();
 
 	speed_bin_index = tm->interface_params[if_id].speed_bin_index;
 	memory_size = tm->interface_params[if_id].memory_size;
 	page_size =
 		(tm->interface_params[if_id].bus_width ==
-		 BUS_WIDTH_8) ? page_param[memory_size].
+		 MV_DDR_DEV_WIDTH_8BIT) ? page_param[memory_size].
 		page_size_8bit : page_param[memory_size].page_size_16bit;
 	t_ckclk = (MEGA / freq_val[frequency]);
+	/* HCLK in[ps] */
+	t_hclk = MEGA / (freq_val[frequency] / config_func_info[dev_num].tip_get_clock_ratio(frequency));
+
+	t_refi = (tm->interface_params[if_id].interface_temp == MV_DDR_TEMP_HIGH) ? TREFI_HIGH : TREFI_LOW;
+	t_refi *= 1000;	/* psec */
+	refresh_interval_cnt = t_refi / t_hclk;	/* no units */
+
+	if (page_size == 1) {
+		t_faw = speed_bin_table(speed_bin_index, SPEED_BIN_TFAW1K);
+		t_faw = time_to_nclk(t_faw, t_ckclk);
+		t_faw = GET_MAX_VALUE(20, t_faw);
+	} else {	/* page size =2, we do not support page size 0.5k */
+		t_faw = speed_bin_table(speed_bin_index, SPEED_BIN_TFAW2K);
+		t_faw = time_to_nclk(t_faw, t_ckclk);
+		t_faw = GET_MAX_VALUE(28, t_faw);
+	}
+
+	t_pd = GET_MAX_VALUE(t_ckclk * 3, speed_bin_table(speed_bin_index, SPEED_BIN_TPD));
+	t_pd = time_to_nclk(t_pd, t_ckclk);
+
+	t_xpdll = GET_MAX_VALUE(t_ckclk * 10, speed_bin_table(speed_bin_index, SPEED_BIN_TXPDLL));
+	t_xpdll = time_to_nclk(t_xpdll, t_ckclk);
+
 	t_rrd =	(page_size == 1) ? speed_bin_table(speed_bin_index,
 						   SPEED_BIN_TRRD1K) :
 		speed_bin_table(speed_bin_index, SPEED_BIN_TRRD2K);
 	t_rrd = GET_MAX_VALUE(t_ckclk * 4, t_rrd);
 	t_rtp =	GET_MAX_VALUE(t_ckclk * 4, speed_bin_table(speed_bin_index,
 							   SPEED_BIN_TRTP));
+	t_mod = GET_MAX_VALUE(t_ckclk * 12, 15000);
 	t_wtr = GET_MAX_VALUE(t_ckclk * 4, speed_bin_table(speed_bin_index,
 							   SPEED_BIN_TWTR));
-	t_ras = TIME_2_CLOCK_CYCLES(speed_bin_table(speed_bin_index,
+	t_ras = time_to_nclk(speed_bin_table(speed_bin_index,
 						    SPEED_BIN_TRAS),
 				    t_ckclk);
-	t_rcd = TIME_2_CLOCK_CYCLES(speed_bin_table(speed_bin_index,
+	t_rcd = time_to_nclk(speed_bin_table(speed_bin_index,
 						    SPEED_BIN_TRCD),
 				    t_ckclk);
-	t_rp = TIME_2_CLOCK_CYCLES(speed_bin_table(speed_bin_index,
+	t_rp = time_to_nclk(speed_bin_table(speed_bin_index,
 						   SPEED_BIN_TRP),
 				   t_ckclk);
-	t_wr = TIME_2_CLOCK_CYCLES(speed_bin_table(speed_bin_index,
+	t_wr = time_to_nclk(speed_bin_table(speed_bin_index,
 						   SPEED_BIN_TWR),
 				   t_ckclk);
-	t_wtr = TIME_2_CLOCK_CYCLES(t_wtr, t_ckclk);
-	t_rrd = TIME_2_CLOCK_CYCLES(t_rrd, t_ckclk);
-	t_rtp = TIME_2_CLOCK_CYCLES(t_rtp, t_ckclk);
-	t_rfc = TIME_2_CLOCK_CYCLES(rfc_table[memory_size] * 1000, t_ckclk);
-	t_mod = GET_MAX_VALUE(t_ckclk * 24, 15000);
-	t_mod = TIME_2_CLOCK_CYCLES(t_mod, t_ckclk);
+	t_wtr = time_to_nclk(t_wtr, t_ckclk);
+	t_rrd = time_to_nclk(t_rrd, t_ckclk);
+	t_rtp = time_to_nclk(t_rtp, t_ckclk);
+	t_rfc = time_to_nclk(rfc_table[memory_size] * 1000, t_ckclk);
+	t_mod = time_to_nclk(t_mod, t_ckclk);
 
 	/* SDRAM Timing Low */
-	val = (t_ras & 0xf) | (t_rcd << 4) | (t_rp << 8) | (t_wr << 12) |
-		(t_wtr << 16) | (((t_ras & 0x30) >> 4) << 20) | (t_rrd << 24) |
-		(t_rtp << 28);
+	val = (((t_ras - 1) & SDRAM_TIMING_LOW_TRAS_MASK) << SDRAM_TIMING_LOW_TRAS_OFFS) |
+	      (((t_rcd - 1) & SDRAM_TIMING_LOW_TRCD_MASK) << SDRAM_TIMING_LOW_TRCD_OFFS) |
+	      (((t_rcd - 1) >> SDRAM_TIMING_LOW_TRCD_OFFS & SDRAM_TIMING_HIGH_TRCD_MASK)
+	      << SDRAM_TIMING_HIGH_TRCD_OFFS) |
+	      (((t_rp - 1) & SDRAM_TIMING_LOW_TRP_MASK) << SDRAM_TIMING_LOW_TRP_OFFS) |
+	      (((t_rp - 1) >> SDRAM_TIMING_LOW_TRP_MASK & SDRAM_TIMING_HIGH_TRP_MASK)
+	      << SDRAM_TIMING_HIGH_TRP_OFFS) |
+	      (((t_wr - 1) & SDRAM_TIMING_LOW_TWR_MASK) << SDRAM_TIMING_LOW_TWR_OFFS) |
+	      (((t_wtr - 1) & SDRAM_TIMING_LOW_TWTR_MASK) << SDRAM_TIMING_LOW_TWTR_OFFS) |
+	      ((((t_ras - 1) >> 4) & SDRAM_TIMING_LOW_TRAS_HIGH_MASK) << SDRAM_TIMING_LOW_TRAS_HIGH_OFFS) |
+	      (((t_rrd - 1) & SDRAM_TIMING_LOW_TRRD_MASK) << SDRAM_TIMING_LOW_TRRD_OFFS) |
+	      (((t_rtp - 1) & SDRAM_TIMING_LOW_TRTP_MASK) << SDRAM_TIMING_LOW_TRTP_OFFS);
+
+	mask = (SDRAM_TIMING_LOW_TRAS_MASK << SDRAM_TIMING_LOW_TRAS_OFFS) |
+	       (SDRAM_TIMING_LOW_TRCD_MASK << SDRAM_TIMING_LOW_TRCD_OFFS) |
+	       (SDRAM_TIMING_HIGH_TRCD_MASK << SDRAM_TIMING_HIGH_TRCD_OFFS) |
+	       (SDRAM_TIMING_LOW_TRP_MASK << SDRAM_TIMING_LOW_TRP_OFFS) |
+	       (SDRAM_TIMING_HIGH_TRP_MASK << SDRAM_TIMING_HIGH_TRP_OFFS) |
+	       (SDRAM_TIMING_LOW_TWR_MASK << SDRAM_TIMING_LOW_TWR_OFFS) |
+	       (SDRAM_TIMING_LOW_TWTR_MASK << SDRAM_TIMING_LOW_TWTR_OFFS) |
+	       (SDRAM_TIMING_LOW_TRAS_HIGH_MASK << SDRAM_TIMING_LOW_TRAS_HIGH_OFFS) |
+	       (SDRAM_TIMING_LOW_TRRD_MASK << SDRAM_TIMING_LOW_TRRD_OFFS) |
+	       (SDRAM_TIMING_LOW_TRTP_MASK << SDRAM_TIMING_LOW_TRTP_OFFS);
+
 	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
-				       SDRAM_TIMING_LOW_REG, val, 0xff3fffff));
+				       SDRAM_TIMING_LOW_REG, val, mask));
 
 	/* SDRAM Timing High */
+	val = 0;
+	mask = 0;
+
+	val = (((t_rfc - 1) & SDRAM_TIMING_HIGH_TRFC_MASK) << SDRAM_TIMING_HIGH_TRFC_OFFS) |
+	      ((t_r2r & SDRAM_TIMING_HIGH_TR2R_MASK) << SDRAM_TIMING_HIGH_TR2R_OFFS) |
+	      ((t_r2w_w2r & SDRAM_TIMING_HIGH_TR2W_W2R_MASK) << SDRAM_TIMING_HIGH_TR2W_W2R_OFFS) |
+	      ((t_w2w & SDRAM_TIMING_HIGH_TW2W_MASK) << SDRAM_TIMING_HIGH_TW2W_OFFS) |
+	      ((((t_rfc - 1) >> 7) & SDRAM_TIMING_HIGH_TRFC_HIGH_MASK) << SDRAM_TIMING_HIGH_TRFC_HIGH_OFFS) |
+	      ((t_r2r_high & SDRAM_TIMING_HIGH_TR2R_HIGH_MASK) << SDRAM_TIMING_HIGH_TR2R_HIGH_OFFS) |
+	      ((t_r2w_w2r_high & SDRAM_TIMING_HIGH_TR2W_W2R_HIGH_MASK) << SDRAM_TIMING_HIGH_TR2W_W2R_HIGH_OFFS) |
+	      (((t_mod - 1) & SDRAM_TIMING_HIGH_TMOD_MASK) << SDRAM_TIMING_HIGH_TMOD_OFFS) |
+	      ((((t_mod - 1) >> 4) & SDRAM_TIMING_HIGH_TMOD_HIGH_MASK) << SDRAM_TIMING_HIGH_TMOD_HIGH_OFFS);
+
+	mask = (SDRAM_TIMING_HIGH_TRFC_MASK << SDRAM_TIMING_HIGH_TRFC_OFFS) |
+	       (SDRAM_TIMING_HIGH_TR2R_MASK << SDRAM_TIMING_HIGH_TR2R_OFFS) |
+	       (SDRAM_TIMING_HIGH_TR2W_W2R_MASK << SDRAM_TIMING_HIGH_TR2W_W2R_OFFS) |
+	       (SDRAM_TIMING_HIGH_TW2W_MASK << SDRAM_TIMING_HIGH_TW2W_OFFS) |
+	       (SDRAM_TIMING_HIGH_TRFC_HIGH_MASK << SDRAM_TIMING_HIGH_TRFC_HIGH_OFFS) |
+	       (SDRAM_TIMING_HIGH_TR2R_HIGH_MASK << SDRAM_TIMING_HIGH_TR2R_HIGH_OFFS) |
+	       (SDRAM_TIMING_HIGH_TR2W_W2R_HIGH_MASK << SDRAM_TIMING_HIGH_TR2W_W2R_HIGH_OFFS) |
+	       (SDRAM_TIMING_HIGH_TMOD_MASK << SDRAM_TIMING_HIGH_TMOD_OFFS) |
+	       (SDRAM_TIMING_HIGH_TMOD_HIGH_MASK << SDRAM_TIMING_HIGH_TMOD_HIGH_OFFS);
+
 	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
-				       SDRAM_TIMING_HIGH_REG,
-				       t_rfc & 0x7f, 0x7f));
-	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
-				       SDRAM_TIMING_HIGH_REG,
-				       0x180, 0x180));
-	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
-				       SDRAM_TIMING_HIGH_REG,
-				       0x600, 0x600));
-	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
-				       SDRAM_TIMING_HIGH_REG,
-				       0x1800, 0xf800));
-	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
-				       SDRAM_TIMING_HIGH_REG,
-				       ((t_rfc & 0x380) >> 7) << 16, 0x70000));
-	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
-				       SDRAM_TIMING_HIGH_REG, 0,
-				       0x380000));
-	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
-				       SDRAM_TIMING_HIGH_REG,
-				       (t_mod & 0xf) << 25, 0x1e00000));
-	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
-				       SDRAM_TIMING_HIGH_REG,
-				       (t_mod >> 4) << 30, 0xc0000000));
+				       SDRAM_TIMING_HIGH_REG, val, mask));
+
 	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
-				       SDRAM_TIMING_HIGH_REG,
-				       0x16000000, 0x1e000000));
+				       SDRAM_CFG_REG,
+				       refresh_interval_cnt << REFRESH_OFFS,
+				       REFRESH_MASK << REFRESH_OFFS));
 	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
-				       SDRAM_TIMING_HIGH_REG,
-				       0x40000000, 0xc0000000));
+				       SDRAM_ADDR_CTRL_REG, (t_faw - 1) << T_FAW_OFFS,
+				       T_FAW_MASK << T_FAW_OFFS));
+
+	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id, DDR_TIMING_REG,
+				       (t_pd - 1) << DDR_TIMING_TPD_OFFS |
+				       (t_xpdll - 1) << DDR_TIMING_TXPDLL_OFFS,
+				       DDR_TIMING_TPD_MASK << DDR_TIMING_TPD_OFFS |
+				       DDR_TIMING_TXPDLL_MASK << DDR_TIMING_TXPDLL_OFFS));
+
 
 	return MV_OK;
 }
 
+
 /*
  * Mode Read
  */
@@ -1713,13 +1847,13 @@ int hws_ddr3_tip_mode_read(u32 dev_num, struct mode_info *mode_info)
 		return ret;
 
 	ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			       READ_DATA_SAMPLE_DELAY, mode_info->read_data_sample,
+			       RD_DATA_SMPL_DLYS_REG, mode_info->read_data_sample,
 			       MASK_ALL_BITS);
 	if (ret != MV_OK)
 		return ret;
 
 	ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			       READ_DATA_READY_DELAY, mode_info->read_data_ready,
+			       RD_DATA_RDY_DLYS_REG, mode_info->read_data_ready,
 			       MASK_ALL_BITS);
 	if (ret != MV_OK)
 		return ret;
@@ -1734,10 +1868,10 @@ int ddr3_tip_get_first_active_if(u8 dev_num, u32 interface_mask,
 				 u32 *interface_id)
 {
 	u32 if_id;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		if (interface_mask & (1 << if_id)) {
 			*interface_id = if_id;
 			break;
@@ -1753,13 +1887,14 @@ int ddr3_tip_get_first_active_if(u8 dev_num, u32 interface_mask,
 int ddr3_tip_write_cs_result(u32 dev_num, u32 offset)
 {
 	u32 if_id, bus_num, cs_bitmask, data_val, cs_num;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-		for (bus_num = 0; bus_num < tm->num_of_bus_per_interface;
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+		for (bus_num = 0; bus_num < octets_per_if_num;
 		     bus_num++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, bus_num);
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_num);
 			cs_bitmask =
 				tm->interface_params[if_id].
 				as_bus_params[bus_num].cs_bitmask;
@@ -1769,7 +1904,7 @@ int ddr3_tip_write_cs_result(u32 dev_num, u32 offset)
 						  ACCESS_TYPE_UNICAST, bus_num,
 						  DDR_PHY_DATA,
 						  offset +
-						  CS_REG_VALUE(effective_cs),
+						  (effective_cs * 0x4),
 						  &data_val);
 				ddr3_tip_bus_write(dev_num,
 						   ACCESS_TYPE_UNICAST,
@@ -1777,7 +1912,7 @@ int ddr3_tip_write_cs_result(u32 dev_num, u32 offset)
 						   ACCESS_TYPE_UNICAST,
 						   bus_num, DDR_PHY_DATA,
 						   offset +
-						   CS_REG_VALUE(cs_num),
+						   (cs_num * 0x4),
 						   data_val);
 			}
 		}
@@ -1789,27 +1924,25 @@ int ddr3_tip_write_cs_result(u32 dev_num, u32 offset)
 /*
  * Write MRS
  */
-int ddr3_tip_write_mrs_cmd(u32 dev_num, u32 *cs_mask_arr, u32 cmd,
-			   u32 data, u32 mask)
+int ddr3_tip_write_mrs_cmd(u32 dev_num, u32 *cs_mask_arr, enum mr_number mr_num, u32 data, u32 mask)
 {
-	u32 if_id, reg;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 if_id;
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
-	reg = (cmd == MRS1_CMD) ? MR1_REG : MR2_REG;
 	CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
-				       PARAM_NOT_CARE, reg, data, mask));
+				       PARAM_NOT_CARE, mr_data[mr_num].reg_addr, data, mask));
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      SDRAM_OPERATION_REG,
-			      (cs_mask_arr[if_id] << 8) | cmd, 0xf1f));
+			      SDRAM_OP_REG,
+			      (cs_mask_arr[if_id] << 8) | mr_data[mr_num].cmd, 0xf1f));
 	}
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		if (ddr3_tip_if_polling(dev_num, ACCESS_TYPE_UNICAST, if_id, 0,
-					0x1f, SDRAM_OPERATION_REG,
+					0x1f, SDRAM_OP_REG,
 					MAX_POLLING_ITERATIONS) != MV_OK) {
 			DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
 					  ("write_mrs_cmd: Poll cmd fail"));
@@ -1864,35 +1997,57 @@ int ddr3_tip_reset_fifo_ptr(u32 dev_num)
 int ddr3_tip_ddr3_reset_phy_regs(u32 dev_num)
 {
 	u32 if_id, phy_id, cs;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-		for (phy_id = 0; phy_id < tm->num_of_bus_per_interface;
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+		for (phy_id = 0; phy_id < octets_per_if_num;
 		     phy_id++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, phy_id);
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, phy_id);
 			CHECK_STATUS(ddr3_tip_bus_write
 				     (dev_num, ACCESS_TYPE_UNICAST,
 				      if_id, ACCESS_TYPE_UNICAST,
 				      phy_id, DDR_PHY_DATA,
-				      WL_PHY_REG +
-				      CS_REG_VALUE(effective_cs),
+				      WL_PHY_REG(effective_cs),
 				      phy_reg0_val));
 			CHECK_STATUS(ddr3_tip_bus_write
 				     (dev_num, ACCESS_TYPE_UNICAST, if_id,
 				      ACCESS_TYPE_UNICAST, phy_id, DDR_PHY_DATA,
-				      RL_PHY_REG + CS_REG_VALUE(effective_cs),
+				      RL_PHY_REG(effective_cs),
 				      phy_reg2_val));
 			CHECK_STATUS(ddr3_tip_bus_write
 				     (dev_num, ACCESS_TYPE_UNICAST, if_id,
 				      ACCESS_TYPE_UNICAST, phy_id, DDR_PHY_DATA,
-				      READ_CENTRALIZATION_PHY_REG +
-				      CS_REG_VALUE(effective_cs), phy_reg3_val));
+				      CRX_PHY_REG(effective_cs), phy_reg3_val));
+			CHECK_STATUS(ddr3_tip_bus_write
+				     (dev_num, ACCESS_TYPE_UNICAST, if_id,
+				      ACCESS_TYPE_UNICAST, phy_id, DDR_PHY_DATA,
+				      CTX_PHY_REG(effective_cs), phy_reg1_val));
+			CHECK_STATUS(ddr3_tip_bus_write
+				     (dev_num, ACCESS_TYPE_UNICAST, if_id,
+				      ACCESS_TYPE_UNICAST, phy_id, DDR_PHY_DATA,
+				      PBS_TX_BCAST_PHY_REG(effective_cs), 0x0));
 			CHECK_STATUS(ddr3_tip_bus_write
 				     (dev_num, ACCESS_TYPE_UNICAST, if_id,
 				      ACCESS_TYPE_UNICAST, phy_id, DDR_PHY_DATA,
-				      WRITE_CENTRALIZATION_PHY_REG +
-				      CS_REG_VALUE(effective_cs), phy_reg3_val));
+				      PBS_RX_BCAST_PHY_REG(effective_cs), 0));
+			CHECK_STATUS(ddr3_tip_bus_write
+				     (dev_num, ACCESS_TYPE_UNICAST, if_id,
+				      ACCESS_TYPE_UNICAST, phy_id, DDR_PHY_DATA,
+				      PBS_TX_PHY_REG(effective_cs, DQSP_PAD), 0));
+			CHECK_STATUS(ddr3_tip_bus_write
+				     (dev_num, ACCESS_TYPE_UNICAST, if_id,
+				      ACCESS_TYPE_UNICAST, phy_id, DDR_PHY_DATA,
+				      PBS_RX_PHY_REG(effective_cs, DQSP_PAD), 0));
+			CHECK_STATUS(ddr3_tip_bus_write
+				     (dev_num, ACCESS_TYPE_UNICAST, if_id,
+				      ACCESS_TYPE_UNICAST, phy_id, DDR_PHY_DATA,
+				      PBS_TX_PHY_REG(effective_cs, DQSN_PAD), 0));
+			CHECK_STATUS(ddr3_tip_bus_write
+				     (dev_num, ACCESS_TYPE_UNICAST, if_id,
+				      ACCESS_TYPE_UNICAST, phy_id, DDR_PHY_DATA,
+				      PBS_RX_PHY_REG(effective_cs, DQSN_PAD), 0));
 		}
 	}
 
@@ -1902,7 +2057,7 @@ int ddr3_tip_ddr3_reset_phy_regs(u32 dev_num)
 		CHECK_STATUS(ddr3_tip_bus_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
 			      ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      DDR_PHY_DATA, CSN_IOB_VREF_REG(cs), 63));
+			      DDR_PHY_DATA, VREF_BCAST_PHY_REG(cs), 63));
 	}
 
 	return MV_OK;
@@ -1915,16 +2070,18 @@ int ddr3_tip_restore_dunit_regs(u32 dev_num)
 {
 	u32 index_cnt;
 
+	mv_ddr_set_calib_controller();
+
 	CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
-				       PARAM_NOT_CARE, CALIB_MACHINE_CTRL_REG,
+				       PARAM_NOT_CARE, MAIN_PADS_CAL_MACH_CTRL_REG,
 				       0x1, 0x1));
 	CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
-				       PARAM_NOT_CARE, CALIB_MACHINE_CTRL_REG,
+				       PARAM_NOT_CARE, MAIN_PADS_CAL_MACH_CTRL_REG,
 				       calibration_update_control << 3,
 				       0x3 << 3));
 	CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
 				       PARAM_NOT_CARE,
-				       ODPG_WRITE_READ_MODE_ENABLE_REG,
+				       ODPG_WR_RD_MODE_ENA_REG,
 				       0xffff, MASK_ALL_BITS));
 
 	for (index_cnt = 0; index_cnt < ARRAY_SIZE(odpg_default_value);
@@ -1939,39 +2096,72 @@ int ddr3_tip_restore_dunit_regs(u32 dev_num)
 	return MV_OK;
 }
 
+int ddr3_tip_adll_regs_bypass(u32 dev_num, u32 reg_val1, u32 reg_val2)
+{
+	u32 if_id, phy_id;
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+
+	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+		for (phy_id = 0; phy_id < octets_per_if_num; phy_id++) {
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, phy_id);
+			CHECK_STATUS(ddr3_tip_bus_write
+				     (dev_num, ACCESS_TYPE_UNICAST, if_id,
+				     ACCESS_TYPE_UNICAST, phy_id, DDR_PHY_DATA,
+				     CTX_PHY_REG(effective_cs), reg_val1));
+			CHECK_STATUS(ddr3_tip_bus_write
+				     (dev_num, ACCESS_TYPE_UNICAST, if_id,
+				     ACCESS_TYPE_UNICAST, phy_id, DDR_PHY_DATA,
+				     PBS_TX_BCAST_PHY_REG(effective_cs), reg_val2));
+		}
+	}
+
+	return MV_OK;
+}
+
 /*
  * Auto tune main flow
  */
 static int ddr3_tip_ddr3_training_main_flow(u32 dev_num)
 {
-	enum hws_ddr_freq freq = init_freq;
+/* TODO: enable this functionality for other platforms */
+#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X)
 	struct init_cntr_param init_cntr_prm;
+#endif
 	int ret = MV_OK;
+	int adll_bypass_flag = 0;
 	u32 if_id;
-	u32 max_cs = hws_ddr3_tip_max_cs_get();
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 max_cs = ddr3_tip_max_cs_get(dev_num);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+	enum hws_ddr_freq freq = tm->interface_params[0].memory_freq;
 
-#ifndef EXCLUDE_SWITCH_DEBUG
+#ifdef DDR_VIEWER_TOOL
 	if (debug_training == DEBUG_LEVEL_TRACE) {
 		CHECK_STATUS(print_device_info((u8)dev_num));
 	}
 #endif
 
+	ddr3_tip_validate_algo_components(dev_num);
+
 	for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
 		CHECK_STATUS(ddr3_tip_ddr3_reset_phy_regs(dev_num));
 	}
 	/* Set to 0 after each loop to avoid illegal value may be used */
 	effective_cs = 0;
 
-	freq = init_freq;
+	freq_val[DDR_FREQ_LOW_FREQ] = dfs_low_freq;
+
 	if (is_pll_before_init != 0) {
 		for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 			config_func_info[dev_num].tip_set_freq_divider_func(
 				(u8)dev_num, if_id, freq);
 		}
 	}
 
+/* TODO: enable this functionality for other platforms */
+#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X)
 	if (is_adll_calib_before_init != 0) {
 		DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
 				  ("with adll calib before init\n"));
@@ -2002,10 +2192,25 @@ static int ddr3_tip_ddr3_training_main_flow(u32 dev_num)
 				return MV_FAIL;
 		}
 	}
+#endif
 
+	ret = adll_calibration(dev_num, ACCESS_TYPE_MULTICAST, 0, freq);
+	if (ret != MV_OK) {
+		DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+			("adll_calibration failure\n"));
+		if (debug_mode == 0)
+			return MV_FAIL;
+	}
 
 	if (mask_tune_func & SET_LOW_FREQ_MASK_BIT) {
 		training_stage = SET_LOW_FREQ;
+
+		for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
+			ddr3_tip_adll_regs_bypass(dev_num, 0, 0x1f);
+			adll_bypass_flag = 1;
+		}
+		effective_cs = 0;
+
 		DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
 				  ("SET_LOW_FREQ_MASK_BIT %d\n",
 				   freq_val[low_freq]));
@@ -2021,6 +2226,21 @@ static int ddr3_tip_ddr3_training_main_flow(u32 dev_num)
 		}
 	}
 
+	if (mask_tune_func & WRITE_LEVELING_LF_MASK_BIT) {
+		training_stage = WRITE_LEVELING_LF;
+		DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+			("WRITE_LEVELING_LF_MASK_BIT\n"));
+		ret = ddr3_tip_dynamic_write_leveling(dev_num, 1);
+		if (is_reg_dump != 0)
+			ddr3_tip_reg_dump(dev_num);
+		if (ret != MV_OK) {
+			DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+				("ddr3_tip_dynamic_write_leveling LF failure\n"));
+			if (debug_mode == 0)
+				return MV_FAIL;
+		}
+	}
+
 	for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
 		if (mask_tune_func & LOAD_PATTERN_MASK_BIT) {
 			training_stage = LOAD_PATTERN;
@@ -2039,6 +2259,14 @@ static int ddr3_tip_ddr3_training_main_flow(u32 dev_num)
 			}
 		}
 	}
+
+	if (adll_bypass_flag == 1) {
+		for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
+			ddr3_tip_adll_regs_bypass(dev_num, phy_reg1_val, 0);
+			adll_bypass_flag = 0;
+		}
+	}
+
 	/* Set to 0 after each loop to avoid illegal value may be used */
 	effective_cs = 0;
 
@@ -2065,7 +2293,7 @@ static int ddr3_tip_ddr3_training_main_flow(u32 dev_num)
 		DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
 				  ("WRITE_LEVELING_MASK_BIT\n"));
 		if ((rl_mid_freq_wa == 0) || (freq_val[medium_freq] == 533)) {
-			ret = ddr3_tip_dynamic_write_leveling(dev_num);
+			ret = ddr3_tip_dynamic_write_leveling(dev_num, 0);
 		} else {
 			/* Use old WL */
 			ret = ddr3_tip_legacy_dynamic_write_leveling(dev_num);
@@ -2189,6 +2417,12 @@ static int ddr3_tip_ddr3_training_main_flow(u32 dev_num)
 					PARAM_NOT_CARE,
 					tm->interface_params[first_active_if].
 					memory_freq);
+#if defined(A70X0) || defined(A80X0)
+	if (apn806_rev_id_get() == APN806_REV_ID_A0) {
+		reg_write(0x6f812c, extension_avs);
+		reg_write(0x6f8130, nominal_avs);
+	}
+#endif /* #if defined(A70X0) || defined(A80X0) */
 		if (is_reg_dump != 0)
 			ddr3_tip_reg_dump(dev_num);
 		if (ret != MV_OK) {
@@ -2203,7 +2437,7 @@ static int ddr3_tip_ddr3_training_main_flow(u32 dev_num)
 		training_stage = WRITE_LEVELING_TF;
 		DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
 				  ("WRITE_LEVELING_TF_MASK_BIT\n"));
-		ret = ddr3_tip_dynamic_write_leveling(dev_num);
+		ret = ddr3_tip_dynamic_write_leveling(dev_num, 0);
 		if (is_reg_dump != 0)
 			ddr3_tip_reg_dump(dev_num);
 		if (ret != MV_OK) {
@@ -2245,6 +2479,21 @@ static int ddr3_tip_ddr3_training_main_flow(u32 dev_num)
 		}
 	}
 
+	if (mask_tune_func & RL_DQS_BURST_MASK_BIT) {
+		training_stage = READ_LEVELING_TF;
+		DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+				  ("RL_DQS_BURST_MASK_BIT\n"));
+		ret = mv_ddr_rl_dqs_burst(0, 0, tm->interface_params[0].memory_freq);
+		if (is_reg_dump != 0)
+			ddr3_tip_reg_dump(dev_num);
+		if (ret != MV_OK) {
+			DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+					  ("mv_ddr_rl_dqs_burst TF failure\n"));
+			if (debug_mode == 0)
+				return MV_FAIL;
+		}
+	}
+
 	if (mask_tune_func & DM_PBS_TX_MASK_BIT) {
 		DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("DM_PBS_TX_MASK_BIT\n"));
 	}
@@ -2312,6 +2561,7 @@ static int ddr3_tip_ddr3_training_main_flow(u32 dev_num)
 	/* Set to 0 after each loop to avoid illegal value may be used */
 	effective_cs = 0;
 
+
 	for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
 		if (mask_tune_func & CENTRALIZATION_TX_MASK_BIT) {
 			training_stage = CENTRALIZATION_TX;
@@ -2348,7 +2598,8 @@ static int ddr3_tip_ddr3_training_main_flow(u32 dev_num)
  */
 static int ddr3_tip_ddr3_auto_tune(u32 dev_num)
 {
-	u32 if_id, stage, ret;
+	int status;
+	u32 if_id, stage;
 	int is_if_fail = 0, is_auto_tune_fail = 0;
 
 	training_stage = INIT_CONTROLLER;
@@ -2358,7 +2609,7 @@ static int ddr3_tip_ddr3_auto_tune(u32 dev_num)
 			training_result[stage][if_id] = NO_TEST_DONE;
 	}
 
-	ret = ddr3_tip_ddr3_training_main_flow(dev_num);
+	status = ddr3_tip_ddr3_training_main_flow(dev_num);
 
 	/* activate XSB test */
 	if (xsb_validate_type != 0) {
@@ -2372,9 +2623,11 @@ static int ddr3_tip_ddr3_auto_tune(u32 dev_num)
 	/* print log */
 	CHECK_STATUS(ddr3_tip_print_log(dev_num, window_mem_addr));
 
-	if (ret != MV_OK) {
+#ifndef EXCLUDE_DEBUG_PRINTS
+	if (status != MV_OK) {
 		CHECK_STATUS(ddr3_tip_print_stability_log(dev_num));
 	}
+#endif /* EXCLUDE_DEBUG_PRINTS */
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
 		is_if_fail = 0;
@@ -2390,7 +2643,20 @@ static int ddr3_tip_ddr3_auto_tune(u32 dev_num)
 		}
 	}
 
-	if ((ret == MV_FAIL) || (is_auto_tune_fail == 1))
+	if (((status == MV_FAIL) && (is_auto_tune_fail == 0)) ||
+	    ((status == MV_OK) && (is_auto_tune_fail == 1))) {
+		/*
+		 * If MainFlow result and trainingResult DB not in sync,
+		 * issue warning (caused by no update of trainingResult DB
+		 * when failed)
+		 */
+		DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+				  ("Warning: Algorithm return value and Result DB"
+				   "are not synced (status 0x%x  result DB %d)\n",
+				   status, is_auto_tune_fail));
+	}
+
+	if ((status != MV_OK) || (is_auto_tune_fail == 1))
 		return MV_FAIL;
 	else
 		return MV_OK;
@@ -2403,18 +2669,19 @@ int ddr3_tip_enable_init_sequence(u32 dev_num)
 {
 	int is_fail = 0;
 	u32 if_id = 0, mem_mask = 0, bus_index = 0;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	/* Enable init sequence */
 	CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST, 0,
-				       SDRAM_INIT_CONTROL_REG, 0x1, 0x1));
+				       SDRAM_INIT_CTRL_REG, 0x1, 0x1));
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 
 		if (ddr3_tip_if_polling
 		    (dev_num, ACCESS_TYPE_UNICAST, if_id, 0, 0x1,
-		     SDRAM_INIT_CONTROL_REG,
+		     SDRAM_INIT_CTRL_REG,
 		     MAX_POLLING_ITERATIONS) != MV_OK) {
 			DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
 					  ("polling failed IF %d\n",
@@ -2424,9 +2691,9 @@ int ddr3_tip_enable_init_sequence(u32 dev_num)
 		}
 
 		mem_mask = 0;
-		for (bus_index = 0; bus_index < GET_TOPOLOGY_NUM_OF_BUSES();
+		for (bus_index = 0; bus_index < octets_per_if_num;
 		     bus_index++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, bus_index);
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_index);
 			mem_mask |=
 				tm->interface_params[if_id].
 				as_bus_params[bus_index].mirror_enable_bitmask;
@@ -2436,7 +2703,7 @@ int ddr3_tip_enable_init_sequence(u32 dev_num)
 			/* Disable Multi CS */
 			CHECK_STATUS(ddr3_tip_if_write
 				     (dev_num, ACCESS_TYPE_MULTICAST,
-				      if_id, CS_ENABLE_REG, 1 << 3,
+				      if_id, DUAL_DUNIT_CFG_REG, 1 << 3,
 				      1 << 3));
 		}
 	}
@@ -2513,7 +2780,7 @@ u8 ddr3_tip_get_buf_max(u8 *buf_ptr)
 
 u32 hws_ddr3_get_bus_width(void)
 {
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	return (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask) ==
 		1) ? 16 : 32;
@@ -2521,18 +2788,18 @@ u32 hws_ddr3_get_bus_width(void)
 
 u32 hws_ddr3_get_device_width(u32 if_id)
 {
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	return (tm->interface_params[if_id].bus_width ==
-		BUS_WIDTH_8) ? 8 : 16;
+		MV_DDR_DEV_WIDTH_8BIT) ? 8 : 16;
 }
 
 u32 hws_ddr3_get_device_size(u32 if_id)
 {
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	if (tm->interface_params[if_id].memory_size >=
-	    MEM_SIZE_LAST) {
+	    MV_DDR_DIE_CAP_LAST) {
 		DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
 				  ("Error: Wrong device size of Cs: %d",
 				   tm->interface_params[if_id].memory_size));
@@ -2586,14 +2853,13 @@ int hws_ddr3_cs_base_adr_calc(u32 if_id, u32 cs, u32 *cs_base_addr)
 		return MV_FAIL;
 
 #ifdef DEVICE_MAX_DRAM_ADDRESS_SIZE
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 	/*
 	 * if number of address pins doesn't allow to use max mem size that
 	 * is defined in topology mem size is defined by
 	 * DEVICE_MAX_DRAM_ADDRESS_SIZE
 	 */
-	physical_mem_size =
-		mv_hwsmem_size[tm->interface_params[0].memory_size];
+	physical_mem_size = mem_size[tm->interface_params[0].memory_size];
 
 	if (hws_ddr3_get_device_width(cs) == 16) {
 		/*
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_bist.c b/drivers/ddr/marvell/a38x/ddr3_training_bist.c
index bd0e26068e39..2bab1c7c3226 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training_bist.c
+++ b/drivers/ddr/marvell/a38x/ddr3_training_bist.c
@@ -4,12 +4,6 @@
  * SPDX-License-Identifier:	GPL-2.0
  */
 
-#include <common.h>
-#include <spl.h>
-#include <asm/io.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/soc.h>
-
 #include "ddr3_init.h"
 
 static u32 bist_offset = 32;
@@ -25,7 +19,7 @@ static int ddr3_tip_bist_operation(u32 dev_num,
  */
 int ddr3_tip_bist_activate(u32 dev_num, enum hws_pattern pattern,
 			   enum hws_access_type access_type, u32 if_num,
-			   enum hws_dir direction,
+			   enum hws_dir dir,
 			   enum hws_stress_jump addr_stress_jump,
 			   enum hws_pattern_duration duration,
 			   enum hws_bist_operation oper_type,
@@ -33,103 +27,43 @@ int ddr3_tip_bist_activate(u32 dev_num, enum hws_pattern pattern,
 {
 	u32 tx_burst_size;
 	u32 delay_between_burst;
-	u32 rd_mode, val;
-	u32 poll_cnt = 0, max_poll = 1000, i, start_if, end_if;
+	u32 rd_mode;
 	struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
-	u32 read_data[MAX_INTERFACE_NUM];
-	struct hws_topology_map *tm = ddr3_get_topology_map();
-
-	/* ODPG Write enable from BIST */
-	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_num,
-				       ODPG_DATA_CONTROL_REG, 0x1, 0x1));
-	/* ODPG Read enable/disable from BIST */
-	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_num,
-				       ODPG_DATA_CONTROL_REG,
-				       (direction == OPER_READ) ?
-				       0x2 : 0, 0x2));
-	CHECK_STATUS(ddr3_tip_load_pattern_to_odpg(dev_num, access_type, if_num,
-						   pattern, offset));
-
-	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_num,
-				       ODPG_DATA_BUF_SIZE_REG,
-				       pattern_addr_length, MASK_ALL_BITS));
-	tx_burst_size = (direction == OPER_WRITE) ?
+
+	/* odpg bist write enable */
+	ddr3_tip_if_write(0, access_type, 0, ODPG_DATA_CTRL_REG,
+			  (ODPG_WRBUF_WR_CTRL_ENA << ODPG_WRBUF_WR_CTRL_OFFS),
+			  (ODPG_WRBUF_WR_CTRL_MASK << ODPG_WRBUF_WR_CTRL_OFFS));
+
+	/* odpg bist read enable/disable */
+	ddr3_tip_if_write(0, access_type, 0, ODPG_DATA_CTRL_REG,
+			  (dir == OPER_READ) ? (ODPG_WRBUF_RD_CTRL_ENA << ODPG_WRBUF_RD_CTRL_OFFS) :
+					       (ODPG_WRBUF_RD_CTRL_DIS << ODPG_WRBUF_RD_CTRL_OFFS),
+			  (ODPG_WRBUF_RD_CTRL_MASK << ODPG_WRBUF_RD_CTRL_OFFS));
+
+	ddr3_tip_load_pattern_to_odpg(0, access_type, 0, pattern, offset);
+
+	ddr3_tip_if_write(0, access_type, 0, ODPG_DATA_BUFFER_SIZE_REG, pattern_addr_length, MASK_ALL_BITS);
+	tx_burst_size = (dir == OPER_WRITE) ?
 		pattern_table[pattern].tx_burst_size : 0;
-	delay_between_burst = (direction == OPER_WRITE) ? 2 : 0;
-	rd_mode = (direction == OPER_WRITE) ? 1 : 0;
-	CHECK_STATUS(ddr3_tip_configure_odpg
-		     (dev_num, access_type, if_num, direction,
+	delay_between_burst = (dir == OPER_WRITE) ? 2 : 0;
+	rd_mode = (dir == OPER_WRITE) ? 1 : 0;
+	ddr3_tip_configure_odpg(0, access_type, 0, dir,
 		      pattern_table[pattern].num_of_phases_tx, tx_burst_size,
 		      pattern_table[pattern].num_of_phases_rx,
 		      delay_between_burst,
-		      rd_mode, cs_num, addr_stress_jump, duration));
-	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_num,
-				       ODPG_PATTERN_ADDR_OFFSET_REG,
-				       offset, MASK_ALL_BITS));
+		      rd_mode, cs_num, addr_stress_jump, duration);
+	ddr3_tip_if_write(0, access_type, 0, ODPG_DATA_BUFFER_OFFS_REG, offset, MASK_ALL_BITS);
+
 	if (oper_type == BIST_STOP) {
-		CHECK_STATUS(ddr3_tip_bist_operation(dev_num, access_type,
-						     if_num, BIST_STOP));
+		ddr3_tip_bist_operation(0, access_type, 0, BIST_STOP);
 	} else {
-		CHECK_STATUS(ddr3_tip_bist_operation(dev_num, access_type,
-						     if_num, BIST_START));
-		if (duration != DURATION_CONT) {
-			/*
-			 * This pdelay is a WA, becuase polling fives "done"
-			 * also the odpg did nmot finish its task
-			 */
-			if (access_type == ACCESS_TYPE_MULTICAST) {
-				start_if = 0;
-				end_if = MAX_INTERFACE_NUM - 1;
-			} else {
-				start_if = if_num;
-				end_if = if_num;
-			}
-
-			for (i = start_if; i <= end_if; i++) {
-				VALIDATE_ACTIVE(tm->
-						   if_act_mask, i);
-
-				for (poll_cnt = 0; poll_cnt < max_poll;
-				     poll_cnt++) {
-					CHECK_STATUS(ddr3_tip_if_read
-						     (dev_num,
-						      ACCESS_TYPE_UNICAST,
-						      if_num, ODPG_BIST_DONE,
-						      read_data,
-						      MASK_ALL_BITS));
-					val = read_data[i];
-					if ((val & 0x1) == 0x0) {
-						/*
-						 * In SOC type devices this bit
-						 * is self clear so, if it was
-						 * cleared all good
-						 */
-						break;
-					}
-				}
-
-				if (poll_cnt >= max_poll) {
-					DEBUG_TRAINING_BIST_ENGINE
-						(DEBUG_LEVEL_ERROR,
-						 ("Bist poll failure 2\n"));
-					CHECK_STATUS(ddr3_tip_if_write
-						     (dev_num,
-						      ACCESS_TYPE_UNICAST,
-						      if_num,
-						      ODPG_DATA_CONTROL_REG, 0,
-						      MASK_ALL_BITS));
-					return MV_FAIL;
-				}
-			}
-
-			CHECK_STATUS(ddr3_tip_bist_operation
-				     (dev_num, access_type, if_num, BIST_STOP));
-		}
+		ddr3_tip_bist_operation(0, access_type, 0, BIST_START);
+		if (mv_ddr_is_odpg_done(MAX_POLLING_ITERATIONS) != MV_OK)
+			return MV_FAIL;
+		ddr3_tip_bist_operation(0, access_type, 0, BIST_STOP);
 	}
-
-	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_num,
-				       ODPG_DATA_CONTROL_REG, 0,
-				       MASK_ALL_BITS));
+	ddr3_tip_if_write(0, access_type, 0, ODPG_DATA_CTRL_REG, 0, MASK_ALL_BITS);
 
 	return MV_OK;
 }
@@ -142,34 +76,34 @@ int ddr3_tip_bist_read_result(u32 dev_num, u32 if_id,
 {
 	int ret;
 	u32 read_data[MAX_INTERFACE_NUM];
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
-	if (IS_ACTIVE(tm->if_act_mask, if_id) == 0)
+	if (IS_IF_ACTIVE(tm->if_act_mask, if_id) == 0)
 		return MV_NOT_SUPPORTED;
 	DEBUG_TRAINING_BIST_ENGINE(DEBUG_LEVEL_TRACE,
 				   ("ddr3_tip_bist_read_result if_id %d\n",
 				    if_id));
 	ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_UNICAST, if_id,
-			       ODPG_BIST_FAILED_DATA_HI_REG, read_data,
+			       ODPG_DATA_RX_WORD_ERR_DATA_HIGH_REG, read_data,
 			       MASK_ALL_BITS);
 	if (ret != MV_OK)
 		return ret;
 	pst_bist_result->bist_fail_high = read_data[if_id];
 	ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_UNICAST, if_id,
-			       ODPG_BIST_FAILED_DATA_LOW_REG, read_data,
+			       ODPG_DATA_RX_WORD_ERR_DATA_LOW_REG, read_data,
 			       MASK_ALL_BITS);
 	if (ret != MV_OK)
 		return ret;
 	pst_bist_result->bist_fail_low = read_data[if_id];
 
 	ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_UNICAST, if_id,
-			       ODPG_BIST_LAST_FAIL_ADDR_REG, read_data,
+			       ODPG_DATA_RX_WORD_ERR_ADDR_REG, read_data,
 			       MASK_ALL_BITS);
 	if (ret != MV_OK)
 		return ret;
 	pst_bist_result->bist_last_fail_addr = read_data[if_id];
 	ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_UNICAST, if_id,
-			       ODPG_BIST_DATA_ERROR_COUNTER_REG, read_data,
+			       ODPG_DATA_RX_WORD_ERR_CNTR_REG, read_data,
 			       MASK_ALL_BITS);
 	if (ret != MV_OK)
 		return ret;
@@ -188,10 +122,10 @@ int hws_ddr3_run_bist(u32 dev_num, enum hws_pattern pattern, u32 *result,
 	u32 i = 0;
 	u32 win_base;
 	struct bist_result st_bist_result;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	for (i = 0; i < MAX_INTERFACE_NUM; i++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, i);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, i);
 		hws_ddr3_cs_base_adr_calc(i, cs_num, &win_base);
 		ret = ddr3_tip_bist_activate(dev_num, pattern,
 					     ACCESS_TYPE_UNICAST,
@@ -234,13 +168,10 @@ static int ddr3_tip_bist_operation(u32 dev_num,
 				   enum hws_access_type access_type,
 				   u32 if_id, enum hws_bist_operation oper_type)
 {
-	if (oper_type == BIST_STOP) {
-		CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
-					       ODPG_BIST_DONE, 1 << 8, 1 << 8));
-	} else {
-		CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
-					       ODPG_BIST_DONE, 1, 1));
-	}
+	if (oper_type == BIST_STOP)
+		mv_ddr_odpg_disable();
+	else
+		mv_ddr_odpg_enable();
 
 	return MV_OK;
 }
@@ -254,11 +185,10 @@ void ddr3_tip_print_bist_res(void)
 	u32 i;
 	struct bist_result st_bist_result[MAX_INTERFACE_NUM];
 	int res;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	for (i = 0; i < MAX_INTERFACE_NUM; i++) {
-		if (IS_ACTIVE(tm->if_act_mask, i) == 0)
-			continue;
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, i);
 
 		res = ddr3_tip_bist_read_result(dev_num, i, &st_bist_result[i]);
 		if (res != MV_OK) {
@@ -274,9 +204,7 @@ void ddr3_tip_print_bist_res(void)
 		("interface | error_cnt | fail_low | fail_high | fail_addr\n"));
 
 	for (i = 0; i < MAX_INTERFACE_NUM; i++) {
-		if (IS_ACTIVE(tm->if_act_mask, i) ==
-		    0)
-			continue;
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, i);
 
 		DEBUG_TRAINING_BIST_ENGINE(
 			DEBUG_LEVEL_INFO,
@@ -287,3 +215,389 @@ void ddr3_tip_print_bist_res(void)
 			 st_bist_result[i].bist_last_fail_addr));
 	}
 }
+
+enum {
+	PASS,
+	FAIL
+};
+#define TIP_ITERATION_NUM	31
+static int mv_ddr_tip_bist(enum hws_dir dir, u32 val, enum hws_pattern pattern, u32 cs, u32 *result)
+{
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+	enum hws_training_ip_stat training_result;
+	u16 *reg_map = ddr3_tip_get_mask_results_pup_reg_map();
+	u32 max_subphy = ddr3_tip_dev_attr_get(0, MV_ATTR_OCTET_PER_INTERFACE);
+	u32 subphy, read_data;
+
+	ddr3_tip_ip_training(0, ACCESS_TYPE_MULTICAST, 0, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+			     RESULT_PER_BYTE, HWS_CONTROL_ELEMENT_ADLL, HWS_LOW2HIGH, dir, tm->if_act_mask, val,
+			     TIP_ITERATION_NUM, pattern, EDGE_FP, CS_SINGLE, cs, &training_result);
+
+	for (subphy = 0; subphy < max_subphy; subphy++) {
+		ddr3_tip_if_read(0, ACCESS_TYPE_UNICAST, 0, reg_map[subphy], &read_data, MASK_ALL_BITS);
+		if (((read_data >> BLOCK_STATUS_OFFS) & BLOCK_STATUS_MASK) == BLOCK_STATUS_NOT_LOCKED)
+			*result |= (FAIL << subphy);
+	}
+
+	return MV_OK;
+}
+
+struct interval {
+	u8 *vector;
+	u8 lendpnt;		/* interval's left endpoint */
+	u8 rendpnt;		/* interval's right endpoint */
+	u8 size;		/* interval's size */
+	u8 lmarker;		/* left marker */
+	u8 rmarker;		/* right marker */
+	u8 pass_lendpnt;	/* left endpoint of internal pass interval */
+	u8 pass_rendpnt;	/* right endpoint of internal pass interval */
+};
+
+static int interval_init(u8 *vector, u8 lendpnt, u8 rendpnt,
+			 u8 lmarker, u8 rmarker, struct interval *intrvl)
+{
+	if (intrvl == NULL) {
+		printf("%s: NULL intrvl pointer found\n", __func__);
+		return MV_FAIL;
+	}
+
+	if (vector == NULL) {
+		printf("%s: NULL vector pointer found\n", __func__);
+		return MV_FAIL;
+	}
+	intrvl->vector = vector;
+
+	if (lendpnt >= rendpnt) {
+		printf("%s: incorrect lendpnt and/or rendpnt parameters found\n", __func__);
+		return MV_FAIL;
+	}
+	intrvl->lendpnt = lendpnt;
+	intrvl->rendpnt = rendpnt;
+	intrvl->size = rendpnt - lendpnt + 1;
+
+	if ((lmarker < lendpnt) || (lmarker > rendpnt)) {
+		printf("%s: incorrect lmarker parameter found\n", __func__);
+		return MV_FAIL;
+	}
+	intrvl->lmarker = lmarker;
+
+	if ((rmarker < lmarker) || (rmarker > (intrvl->rendpnt + intrvl->size))) {
+		printf("%s: incorrect rmarker parameter found\n", __func__);
+		return MV_FAIL;
+	}
+	intrvl->rmarker = rmarker;
+
+	return MV_OK;
+}
+static int interval_set(u8 pass_lendpnt, u8 pass_rendpnt, struct interval *intrvl)
+{
+	if (intrvl == NULL) {
+		printf("%s: NULL intrvl pointer found\n", __func__);
+		return MV_FAIL;
+	}
+
+	intrvl->pass_lendpnt = pass_lendpnt;
+	intrvl->pass_rendpnt = pass_rendpnt;
+
+	return MV_OK;
+}
+
+static int interval_proc(struct interval *intrvl)
+{
+	int curr;
+	int pass_lendpnt, pass_rendpnt;
+	int lmt;
+	int fcnt = 0, pcnt = 0;
+
+	if (intrvl == NULL) {
+		printf("%s: NULL intrvl pointer found\n", __func__);
+		return MV_FAIL;
+	}
+
+	/* count fails and passes */
+	curr = intrvl->lendpnt;
+	while (curr <= intrvl->rendpnt) {
+		if (intrvl->vector[curr] == PASS)
+			pcnt++;
+		else
+			fcnt++;
+		curr++;
+	}
+
+	/* check for all fail */
+	if (fcnt == intrvl->size) {
+		printf("%s: no pass found\n", __func__);
+		return MV_FAIL;
+	}
+
+	/* check for all pass */
+	if (pcnt == intrvl->size) {
+		if (interval_set(intrvl->lendpnt, intrvl->rendpnt, intrvl) != MV_OK)
+			return MV_FAIL;
+		return MV_OK;
+	}
+
+	/* proceed with rmarker */
+	curr = intrvl->rmarker;
+	if (intrvl->vector[curr % intrvl->size] == PASS) { /* pass at rmarker */
+		/* search for fail on right */
+		if (intrvl->rmarker > intrvl->rendpnt)
+			lmt = intrvl->rendpnt + intrvl->size;
+		else
+			lmt = intrvl->rmarker + intrvl->size - 1;
+		while ((curr <= lmt) &&
+		       (intrvl->vector[curr % intrvl->size] == PASS))
+			curr++;
+		if (curr > lmt) { /* fail not found */
+			printf("%s: rmarker: fail following pass not found\n", __func__);
+			return MV_FAIL;
+		}
+		/* fail found */
+		pass_rendpnt = curr - 1;
+	} else { /* fail at rmarker */
+		/* search for pass on left */
+		if (intrvl->rmarker > intrvl->rendpnt)
+			lmt = intrvl->rmarker - intrvl->size + 1;
+		else
+			lmt = intrvl->lendpnt;
+		while ((curr >= lmt) &&
+		       (intrvl->vector[curr % intrvl->size] == FAIL))
+			curr--;
+		if (curr < lmt) { /* pass not found */
+			printf("%s: rmarker: pass preceding fail not found\n", __func__);
+			return MV_FAIL;
+		}
+		/* pass found */
+		pass_rendpnt = curr;
+	}
+
+	/* search for fail on left */
+	curr = pass_rendpnt;
+	if (pass_rendpnt > intrvl->rendpnt)
+		lmt =  pass_rendpnt - intrvl->size + 1;
+	else
+		lmt = intrvl->lendpnt;
+	while ((curr >= lmt) &&
+	       (intrvl->vector[curr % intrvl->size] == PASS))
+		curr--;
+	if (curr < lmt) { /* fail not found */
+		printf("%s: rmarker: fail preceding pass not found\n", __func__);
+		return MV_FAIL;
+	}
+	/* fail found */
+	pass_lendpnt = curr + 1;
+	if (interval_set(pass_lendpnt, pass_rendpnt, intrvl) != MV_OK)
+		return MV_FAIL;
+
+	return MV_OK;
+}
+
+#define ADLL_TAPS_PER_PERIOD	64
+int mv_ddr_dm_to_dq_diff_get(u8 vw_sphy_hi_lmt, u8 vw_sphy_lo_lmt, u8 *vw_vector,
+			     int *vw_sphy_hi_diff, int *vw_sphy_lo_diff)
+{
+	struct interval intrvl;
+
+	/* init interval structure */
+	if (interval_init(vw_vector, 0, ADLL_TAPS_PER_PERIOD - 1,
+			  vw_sphy_lo_lmt, vw_sphy_hi_lmt, &intrvl) != MV_OK)
+		return MV_FAIL;
+
+	/* find pass sub-interval */
+	if (interval_proc(&intrvl) != MV_OK)
+		return MV_FAIL;
+
+	/* check for all pass */
+	if ((intrvl.pass_rendpnt == intrvl.rendpnt) &&
+	    (intrvl.pass_lendpnt == intrvl.lendpnt)) {
+		printf("%s: no fail found\n", __func__);
+		return MV_FAIL;
+	}
+
+	*vw_sphy_hi_diff = intrvl.pass_rendpnt - vw_sphy_hi_lmt;
+	*vw_sphy_lo_diff = vw_sphy_lo_lmt - intrvl.pass_lendpnt;
+
+	return MV_OK;
+}
+
+static int mv_ddr_bist_tx(enum hws_access_type access_type)
+{
+	mv_ddr_odpg_done_clr();
+
+	ddr3_tip_bist_operation(0, access_type, 0, BIST_START);
+
+	if (mv_ddr_is_odpg_done(MAX_POLLING_ITERATIONS) != MV_OK)
+		return MV_FAIL;
+
+	ddr3_tip_bist_operation(0, access_type, 0, BIST_STOP);
+
+	ddr3_tip_if_write(0, access_type, 0, ODPG_DATA_CTRL_REG, 0, MASK_ALL_BITS);
+
+	return MV_OK;
+}
+
+/* prepare odpg for bist operation */
+#define WR_OP_ODPG_DATA_CMD_BURST_DLY	2
+static int mv_ddr_odpg_bist_prepare(enum hws_pattern pattern, enum hws_access_type access_type,
+			     enum hws_dir dir, enum hws_stress_jump stress_jump_addr,
+			     enum hws_pattern_duration duration, u32 offset, u32 cs,
+			     u32 pattern_addr_len, enum dm_direction dm_dir)
+{
+	struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
+	u32 tx_burst_size;
+	u32 burst_delay;
+	u32 rd_mode;
+
+	/* odpg bist write enable */
+	ddr3_tip_if_write(0, access_type, 0, ODPG_DATA_CTRL_REG,
+			  (ODPG_WRBUF_WR_CTRL_ENA << ODPG_WRBUF_WR_CTRL_OFFS),
+			  (ODPG_WRBUF_WR_CTRL_MASK << ODPG_WRBUF_WR_CTRL_OFFS));
+
+	/* odpg bist read enable/disable */
+	ddr3_tip_if_write(0, access_type, 0, ODPG_DATA_CTRL_REG,
+			  (dir == OPER_READ) ? (ODPG_WRBUF_RD_CTRL_ENA << ODPG_WRBUF_RD_CTRL_OFFS) :
+					       (ODPG_WRBUF_RD_CTRL_DIS << ODPG_WRBUF_RD_CTRL_OFFS),
+			  (ODPG_WRBUF_RD_CTRL_MASK << ODPG_WRBUF_RD_CTRL_OFFS));
+
+	if (pattern == PATTERN_00 || pattern == PATTERN_FF)
+		ddr3_tip_load_pattern_to_odpg(0, access_type, 0, pattern, offset);
+	else
+		mv_ddr_load_dm_pattern_to_odpg(access_type, pattern, dm_dir);
+
+	ddr3_tip_if_write(0, access_type, 0, ODPG_DATA_BUFFER_SIZE_REG, pattern_addr_len, MASK_ALL_BITS);
+	if (dir == OPER_WRITE) {
+		tx_burst_size = pattern_table[pattern].tx_burst_size;
+		burst_delay = WR_OP_ODPG_DATA_CMD_BURST_DLY;
+		rd_mode = ODPG_MODE_TX;
+	} else {
+		tx_burst_size = 0;
+		burst_delay = 0;
+		rd_mode = ODPG_MODE_RX;
+	}
+	ddr3_tip_configure_odpg(0, access_type, 0, dir, pattern_table[pattern].num_of_phases_tx,
+				tx_burst_size, pattern_table[pattern].num_of_phases_rx, burst_delay,
+				rd_mode, cs, stress_jump_addr, duration);
+
+	return MV_OK;
+}
+
+#define BYTES_PER_BURST_64BIT	0x20
+#define BYTES_PER_BURST_32BIT	0x10
+int mv_ddr_dm_vw_get(enum hws_pattern pattern, u32 cs, u8 *vw_vector)
+{
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+	struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
+	u32 adll_tap;
+	u32 wr_ctrl_adll[MAX_BUS_NUM] = {0};
+	u32 rd_ctrl_adll[MAX_BUS_NUM] = {0};
+	u32 subphy;
+	u32 subphy_max = ddr3_tip_dev_attr_get(0, MV_ATTR_OCTET_PER_INTERFACE);
+	u32 odpg_addr = 0x0;
+	u32 result;
+	u32 idx;
+	/* burst length in bytes */
+	u32 burst_len = (MV_DDR_IS_64BIT_DRAM_MODE(tm->bus_act_mask) ?
+			BYTES_PER_BURST_64BIT : BYTES_PER_BURST_32BIT);
+
+	/* save dqs values to restore after algorithm's run */
+	ddr3_tip_read_adll_value(0, wr_ctrl_adll, CTX_PHY_REG(cs), MASK_ALL_BITS);
+	ddr3_tip_read_adll_value(0, rd_ctrl_adll, CRX_PHY_REG(cs), MASK_ALL_BITS);
+
+	/* fill memory with base pattern */
+	ddr3_tip_if_write(0, ACCESS_TYPE_UNICAST, 0, ODPG_DATA_CTRL_REG, 0, MASK_ALL_BITS);
+	mv_ddr_odpg_bist_prepare(pattern, ACCESS_TYPE_UNICAST, OPER_WRITE, STRESS_NONE, DURATION_SINGLE,
+				 bist_offset, cs, pattern_table[pattern].num_of_phases_tx,
+				 (pattern == PATTERN_00) ? DM_DIR_DIRECT : DM_DIR_INVERSE);
+
+	for (adll_tap = 0; adll_tap < ADLL_TAPS_PER_PERIOD; adll_tap++) {
+		/* change target odpg address */
+		odpg_addr = adll_tap * burst_len;
+		ddr3_tip_if_write(0, ACCESS_TYPE_UNICAST, 0, ODPG_DATA_BUFFER_OFFS_REG,
+				  odpg_addr, MASK_ALL_BITS);
+
+		ddr3_tip_configure_odpg(0, ACCESS_TYPE_UNICAST, 0, OPER_WRITE,
+					pattern_table[pattern].num_of_phases_tx,
+					pattern_table[pattern].tx_burst_size,
+					pattern_table[pattern].num_of_phases_rx,
+					WR_OP_ODPG_DATA_CMD_BURST_DLY,
+					ODPG_MODE_TX, cs, STRESS_NONE, DURATION_SINGLE);
+
+		/* odpg bist write enable */
+		ddr3_tip_if_write(0, ACCESS_TYPE_UNICAST, 0, ODPG_DATA_CTRL_REG,
+				  (ODPG_WRBUF_WR_CTRL_ENA << ODPG_WRBUF_WR_CTRL_OFFS),
+				  (ODPG_WRBUF_WR_CTRL_MASK << ODPG_WRBUF_WR_CTRL_OFFS));
+
+		/* odpg bist read disable */
+		ddr3_tip_if_write(0, ACCESS_TYPE_UNICAST, 0, ODPG_DATA_CTRL_REG,
+				  (ODPG_WRBUF_RD_CTRL_DIS << ODPG_WRBUF_RD_CTRL_OFFS),
+				  (ODPG_WRBUF_RD_CTRL_MASK << ODPG_WRBUF_RD_CTRL_OFFS));
+
+		/* trigger odpg */
+		mv_ddr_bist_tx(ACCESS_TYPE_MULTICAST);
+	}
+
+	/* fill memory with vref pattern to increment addr using odpg bist */
+	mv_ddr_odpg_bist_prepare(PATTERN_VREF, ACCESS_TYPE_UNICAST, OPER_WRITE, STRESS_NONE, DURATION_SINGLE,
+				 bist_offset, cs, pattern_table[pattern].num_of_phases_tx,
+				 (pattern == PATTERN_00) ? DM_DIR_DIRECT : DM_DIR_INVERSE);
+
+	for (adll_tap = 0; adll_tap < ADLL_TAPS_PER_PERIOD; adll_tap++) {
+		ddr3_tip_bus_write(0, ACCESS_TYPE_UNICAST, 0, ACCESS_TYPE_MULTICAST, 0,
+				   DDR_PHY_DATA, CTX_PHY_REG(cs), adll_tap);
+		/* change target odpg address */
+		odpg_addr = adll_tap * burst_len;
+		ddr3_tip_if_write(0, ACCESS_TYPE_UNICAST, 0, ODPG_DATA_BUFFER_OFFS_REG,
+				  odpg_addr, MASK_ALL_BITS);
+		ddr3_tip_configure_odpg(0, ACCESS_TYPE_UNICAST, 0, OPER_WRITE,
+					pattern_table[pattern].num_of_phases_tx,
+					pattern_table[pattern].tx_burst_size,
+					pattern_table[pattern].num_of_phases_rx,
+					WR_OP_ODPG_DATA_CMD_BURST_DLY,
+					ODPG_MODE_TX, cs, STRESS_NONE, DURATION_SINGLE);
+
+		/* odpg bist write enable */
+		ddr3_tip_if_write(0, ACCESS_TYPE_UNICAST, 0, ODPG_DATA_CTRL_REG,
+				  (ODPG_WRBUF_WR_CTRL_ENA << ODPG_WRBUF_WR_CTRL_OFFS),
+				  (ODPG_WRBUF_WR_CTRL_MASK << ODPG_WRBUF_WR_CTRL_OFFS));
+
+		/* odpg bist read disable */
+		ddr3_tip_if_write(0, ACCESS_TYPE_UNICAST, 0, ODPG_DATA_CTRL_REG,
+				  (ODPG_WRBUF_RD_CTRL_DIS << ODPG_WRBUF_RD_CTRL_OFFS),
+				  (ODPG_WRBUF_RD_CTRL_MASK << ODPG_WRBUF_RD_CTRL_OFFS));
+
+		/* trigger odpg */
+		mv_ddr_bist_tx(ACCESS_TYPE_MULTICAST);
+	}
+
+	/* restore subphy's tx adll_tap to its position */
+	for (subphy = 0; subphy < subphy_max; subphy++) {
+		VALIDATE_BUS_ACTIVE(tm->bus_act_mask, subphy);
+		ddr3_tip_bus_write(0, ACCESS_TYPE_UNICAST, 0, ACCESS_TYPE_UNICAST,
+				   subphy, DDR_PHY_DATA, CTX_PHY_REG(cs),
+				   wr_ctrl_adll[subphy]);
+	}
+
+	/* read and validate bist (comparing with the base pattern) */
+	for (adll_tap = 0; adll_tap < ADLL_TAPS_PER_PERIOD; adll_tap++) {
+		result = 0;
+		odpg_addr = adll_tap * burst_len;
+		/* change addr to fit write */
+		mv_ddr_pattern_start_addr_set(pattern_table, pattern, odpg_addr);
+		mv_ddr_tip_bist(OPER_READ, 0, pattern, 0, &result);
+		for (subphy = 0; subphy < subphy_max; subphy++) {
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, subphy);
+			idx = ADLL_TAPS_PER_PERIOD * subphy + adll_tap;
+			vw_vector[idx] |= ((result >> subphy) & 0x1);
+		}
+	}
+
+	/* restore subphy's rx adll_tap to its position */
+	for (subphy = 0; subphy < subphy_max; subphy++) {
+		VALIDATE_BUS_ACTIVE(tm->bus_act_mask, subphy);
+		ddr3_tip_bus_write(0, ACCESS_TYPE_UNICAST, 0, ACCESS_TYPE_UNICAST,
+				   subphy, DDR_PHY_DATA, CRX_PHY_REG(cs),
+				   rd_ctrl_adll[subphy]);
+	}
+
+	return MV_OK;
+}
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_centralization.c b/drivers/ddr/marvell/a38x/ddr3_training_centralization.c
index 2909ae3c6f9a..e2b6534cf910 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training_centralization.c
+++ b/drivers/ddr/marvell/a38x/ddr3_training_centralization.c
@@ -4,12 +4,6 @@
  * SPDX-License-Identifier:	GPL-2.0
  */
 
-#include <common.h>
-#include <spl.h>
-#include <asm/io.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/soc.h>
-
 #include "ddr3_init.h"
 
 #define VALIDATE_WIN_LENGTH(e1, e2, maxsize)		\
@@ -23,6 +17,7 @@
 #define NUM_OF_CENTRAL_TYPES	2
 
 u32 start_pattern = PATTERN_KILLER_DQ0, end_pattern = PATTERN_KILLER_DQ7;
+
 u32 start_if = 0, end_if = (MAX_INTERFACE_NUM - 1);
 u8 bus_end_window[NUM_OF_CENTRAL_TYPES][MAX_INTERFACE_NUM][MAX_BUS_NUM];
 u8 bus_start_window[NUM_OF_CENTRAL_TYPES][MAX_INTERFACE_NUM][MAX_BUS_NUM];
@@ -66,7 +61,8 @@ static int ddr3_tip_centralization(u32 dev_num, u32 mode)
 	u8 current_window[BUS_WIDTH_IN_BITS];
 	u8 opt_window, waste_window, start_window_skew, end_window_skew;
 	u8 final_pup_window[MAX_INTERFACE_NUM][BUS_WIDTH_IN_BITS];
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 	enum hws_training_result result_type = RESULT_PER_BIT;
 	enum hws_dir direction;
 	u32 *result[HWS_SEARCH_DIR_LIMIT];
@@ -82,33 +78,33 @@ static int ddr3_tip_centralization(u32 dev_num, u32 mode)
 	u8 cons_tap = (mode == CENTRAL_TX) ? (64) : (0);
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		/* save current cs enable reg val */
 		CHECK_STATUS(ddr3_tip_if_read
 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      CS_ENABLE_REG, cs_enable_reg_val, MASK_ALL_BITS));
+			      DUAL_DUNIT_CFG_REG, cs_enable_reg_val, MASK_ALL_BITS));
 		/* enable single cs */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      CS_ENABLE_REG, (1 << 3), (1 << 3)));
+			      DUAL_DUNIT_CFG_REG, (1 << 3), (1 << 3)));
 	}
 
 	if (mode == CENTRAL_TX) {
 		max_win_size = MAX_WINDOW_SIZE_TX;
-		reg_phy_off = WRITE_CENTRALIZATION_PHY_REG + (effective_cs * 4);
+		reg_phy_off = CTX_PHY_REG(effective_cs);
 		direction = OPER_WRITE;
 	} else {
 		max_win_size = MAX_WINDOW_SIZE_RX;
-		reg_phy_off = READ_CENTRALIZATION_PHY_REG + (effective_cs * 4);
+		reg_phy_off = CRX_PHY_REG(effective_cs);
 		direction = OPER_READ;
 	}
 
 	/* DB initialization */
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		for (bus_id = 0;
-		     bus_id < tm->num_of_bus_per_interface; bus_id++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+		     bus_id < octets_per_if_num; bus_id++) {
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
 			centralization_state[if_id][bus_id] = 0;
 			bus_end_window[mode][if_id][bus_id] =
 				(max_win_size - 1) + cons_tap;
@@ -134,11 +130,11 @@ static int ddr3_tip_centralization(u32 dev_num, u32 mode)
 					     PARAM_NOT_CARE, training_result);
 
 		for (if_id = start_if; if_id <= end_if; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 			for (bus_id = 0;
-			     bus_id <= tm->num_of_bus_per_interface - 1;
+			     bus_id <= octets_per_if_num - 1;
 			     bus_id++) {
-				VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+				VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
 
 				for (search_dir_id = HWS_LOW2HIGH;
 				     search_dir_id <= HWS_HIGH2LOW;
@@ -337,8 +333,10 @@ static int ddr3_tip_centralization(u32 dev_num, u32 mode)
 							  [if_id][bus_id]));
 						centralization_state[if_id]
 							[bus_id] = 1;
-						if (debug_mode == 0)
+						if (debug_mode == 0) {
+							flow_result[if_id] = TEST_FAILED;
 							return MV_FAIL;
+						}
 					}
 				}	/* ddr3_tip_centr_skip_min_win_check */
 			}	/* pup */
@@ -346,15 +344,14 @@ static int ddr3_tip_centralization(u32 dev_num, u32 mode)
 	}			/* pattern */
 
 	for (if_id = start_if; if_id <= end_if; if_id++) {
-		if (IS_ACTIVE(tm->if_act_mask, if_id) == 0)
-			continue;
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 
 		is_if_fail = 0;
 		flow_result[if_id] = TEST_SUCCESS;
 
 		for (bus_id = 0;
-		     bus_id <= (tm->num_of_bus_per_interface - 1); bus_id++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+		     bus_id <= (octets_per_if_num - 1); bus_id++) {
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
 
 			/* continue only if lock */
 			if (centralization_state[if_id][bus_id] != 1) {
@@ -441,21 +438,21 @@ static int ddr3_tip_centralization(u32 dev_num, u32 mode)
 				ddr3_tip_bus_read(dev_num, if_id,
 						  ACCESS_TYPE_UNICAST, bus_id,
 						  DDR_PHY_DATA,
-						  RESULT_DB_PHY_REG_ADDR +
+						  RESULT_PHY_REG +
 						  effective_cs, &reg);
 				reg = (reg & (~0x1f <<
 					      ((mode == CENTRAL_TX) ?
-					       (RESULT_DB_PHY_REG_TX_OFFSET) :
-					       (RESULT_DB_PHY_REG_RX_OFFSET))))
+					       (RESULT_PHY_TX_OFFS) :
+					       (RESULT_PHY_RX_OFFS))))
 					| pup_win_length <<
 					((mode == CENTRAL_TX) ?
-					 (RESULT_DB_PHY_REG_TX_OFFSET) :
-					 (RESULT_DB_PHY_REG_RX_OFFSET));
+					 (RESULT_PHY_TX_OFFS) :
+					 (RESULT_PHY_RX_OFFS));
 				CHECK_STATUS(ddr3_tip_bus_write
 					     (dev_num, ACCESS_TYPE_UNICAST,
 					      if_id, ACCESS_TYPE_UNICAST,
 					      bus_id, DDR_PHY_DATA,
-					      RESULT_DB_PHY_REG_ADDR +
+					      RESULT_PHY_REG +
 					      effective_cs, reg));
 
 				/* offset per CS is calculated earlier */
@@ -481,9 +478,9 @@ static int ddr3_tip_centralization(u32 dev_num, u32 mode)
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
 		/* restore cs enable value */
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_UNICAST,
-					       if_id, CS_ENABLE_REG,
+					       if_id, DUAL_DUNIT_CFG_REG,
 					       cs_enable_reg_val[if_id],
 					       MASK_ALL_BITS));
 	}
@@ -509,29 +506,30 @@ int ddr3_tip_special_rx(u32 dev_num)
 	u32 cs_enable_reg_val[MAX_INTERFACE_NUM];
 	u32 temp = 0;
 	int pad_num = 0;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
-	if (ddr3_tip_special_rx_run_once_flag != 0)
+	if ((ddr3_tip_special_rx_run_once_flag & (1 << effective_cs)) == (1 << effective_cs))
 		return MV_OK;
 
-	ddr3_tip_special_rx_run_once_flag = 1;
+	ddr3_tip_special_rx_run_once_flag |= (1 << effective_cs);
 
 	for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		/* save current cs enable reg val */
 		CHECK_STATUS(ddr3_tip_if_read(dev_num, ACCESS_TYPE_UNICAST,
-					      if_id, CS_ENABLE_REG,
+					      if_id, DUAL_DUNIT_CFG_REG,
 					      cs_enable_reg_val,
 					      MASK_ALL_BITS));
 		/* enable single cs */
 		CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_UNICAST,
-					       if_id, CS_ENABLE_REG,
+					       if_id, DUAL_DUNIT_CFG_REG,
 					       (1 << 3), (1 << 3)));
 	}
 
 	max_win_size = MAX_WINDOW_SIZE_RX;
 	direction = OPER_READ;
-	pattern_id = PATTERN_VREF;
+	pattern_id = PATTERN_FULL_SSO1;
 
 	/* start flow */
 	ddr3_tip_ip_training_wrapper(dev_num, ACCESS_TYPE_MULTICAST,
@@ -545,10 +543,10 @@ int ddr3_tip_special_rx(u32 dev_num)
 				     PARAM_NOT_CARE, training_result);
 
 	for (if_id = start_if; if_id <= end_if; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		for (pup_id = 0;
-		     pup_id <= tm->num_of_bus_per_interface; pup_id++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, pup_id);
+		     pup_id <= octets_per_if_num; pup_id++) {
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup_id);
 
 			for (search_dir_id = HWS_LOW2HIGH;
 			     search_dir_id <= HWS_HIGH2LOW;
@@ -621,13 +619,12 @@ int ddr3_tip_special_rx(u32 dev_num)
 							     BUS_WIDTH_IN_BITS +
 							     if_id *
 							     BUS_WIDTH_IN_BITS *
-							     tm->
-							     num_of_bus_per_interface];
+							     MAX_BUS_NUM];
 					CHECK_STATUS(ddr3_tip_bus_read
 						     (dev_num, if_id,
 						      ACCESS_TYPE_UNICAST,
 						      pup_id, DDR_PHY_DATA,
-						      PBS_RX_PHY_REG + pad_num,
+						      PBS_RX_PHY_REG(effective_cs, pad_num),
 						      &temp));
 					temp = (temp + 0xa > 31) ?
 						(31) : (temp + 0xa);
@@ -637,7 +634,7 @@ int ddr3_tip_special_rx(u32 dev_num)
 						      if_id,
 						      ACCESS_TYPE_UNICAST,
 						      pup_id, DDR_PHY_DATA,
-						      PBS_RX_PHY_REG + pad_num,
+						      PBS_RX_PHY_REG(effective_cs, pad_num),
 						      temp));
 				}
 				DEBUG_CENTRALIZATION_ENGINE(
@@ -650,25 +647,29 @@ int ddr3_tip_special_rx(u32 dev_num)
 				CHECK_STATUS(ddr3_tip_bus_read
 					     (dev_num, if_id,
 					      ACCESS_TYPE_UNICAST, pup_id,
-					      DDR_PHY_DATA, PBS_RX_PHY_REG + 4,
+					      DDR_PHY_DATA,
+					      PBS_RX_PHY_REG(effective_cs, 4),
 					      &temp));
 				temp += 0xa;
 				CHECK_STATUS(ddr3_tip_bus_write
 					     (dev_num, ACCESS_TYPE_UNICAST,
 					      if_id, ACCESS_TYPE_UNICAST,
 					      pup_id, DDR_PHY_DATA,
-					      PBS_RX_PHY_REG + 4, temp));
+					      PBS_RX_PHY_REG(effective_cs, 4),
+					      temp));
 				CHECK_STATUS(ddr3_tip_bus_read
 					     (dev_num, if_id,
 					      ACCESS_TYPE_UNICAST, pup_id,
-					      DDR_PHY_DATA, PBS_RX_PHY_REG + 5,
+					      DDR_PHY_DATA,
+					      PBS_RX_PHY_REG(effective_cs, 5),
 					      &temp));
 				temp += 0xa;
 				CHECK_STATUS(ddr3_tip_bus_write
 					     (dev_num, ACCESS_TYPE_UNICAST,
 					      if_id, ACCESS_TYPE_UNICAST,
 					      pup_id, DDR_PHY_DATA,
-					      PBS_RX_PHY_REG + 5, temp));
+					      PBS_RX_PHY_REG(effective_cs, 5),
+					      temp));
 				DEBUG_CENTRALIZATION_ENGINE(
 					DEBUG_LEVEL_INFO,
 					("Special: PBS:: I/F# %d , Bus# %d fix align to the right\n",
@@ -695,15 +696,16 @@ int ddr3_tip_special_rx(u32 dev_num)
 int ddr3_tip_print_centralization_result(u32 dev_num)
 {
 	u32 if_id = 0, bus_id = 0;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	printf("Centralization Results\n");
 	printf("I/F0 Result[0 - success 1-fail 2 - state_2 3 - state_3] ...\n");
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-		for (bus_id = 0; bus_id < tm->num_of_bus_per_interface;
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+		for (bus_id = 0; bus_id < octets_per_if_num;
 		     bus_id++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
 			printf("%d ,\n", centralization_state[if_id][bus_id]);
 		}
 	}
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_db.c b/drivers/ddr/marvell/a38x/ddr3_training_db.c
index 0e11b434ab67..0681eabc9992 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training_db.c
+++ b/drivers/ddr/marvell/a38x/ddr3_training_db.c
@@ -4,16 +4,25 @@
  * SPDX-License-Identifier:	GPL-2.0
  */
 
-#include <common.h>
-#include <spl.h>
-#include <asm/io.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/soc.h>
-
 #include "ddr3_init.h"
 
+/* Device attributes structures */
+enum mv_ddr_dev_attribute ddr_dev_attributes[MAX_DEVICE_NUM][MV_ATTR_LAST];
+int ddr_dev_attr_init_done[MAX_DEVICE_NUM] = { 0 };
+
+static inline u32 pattern_table_get_killer_word16(u8 dqs, u8 index);
+static inline u32 pattern_table_get_sso_word(u8 sso, u8 index);
+static inline u32 pattern_table_get_vref_word(u8 index);
+static inline u32 pattern_table_get_vref_word16(u8 index);
+static inline u32 pattern_table_get_sso_full_xtalk_word(u8 bit, u8 index);
+static inline u32 pattern_table_get_sso_full_xtalk_word16(u8 bit, u8 index);
+static inline u32 pattern_table_get_sso_xtalk_free_word(u8 bit, u8 index);
+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);
+
 /* List of allowed frequency listed in order of enum hws_ddr_freq */
-u32 freq_val[DDR_FREQ_LIMIT] = {
+u32 freq_val[DDR_FREQ_LAST] = {
 	0,			/*DDR_FREQ_LOW_FREQ */
 	400,			/*DDR_FREQ_400, */
 	533,			/*DDR_FREQ_533, */
@@ -152,18 +161,18 @@ u8 twr_mask_table[] = {
 	10,
 	10,
 	10,
-	1,			/*5*/
-	2,			/*6*/
-	3,			/*7*/
-	4,			/*8*/
+	1,			/* 5 */
+	2,			/* 6 */
+	3,			/* 7 */
+	4,			/* 8 */
 	10,
-	5,			/*10*/
+	5,			/* 10 */
 	10,
-	6,			/*12*/
+	6,			/* 12 */
 	10,
-	7,			/*14*/
+	7,			/* 14 */
 	10,
-	0			/*16*/
+	0			/* 16 */
 };
 
 u8 cl_mask_table[] = {
@@ -210,7 +219,11 @@ u16 rfc_table[] = {
 	110,			/* 1G */
 	160,			/* 2G */
 	260,			/* 4G */
-	350			/* 8G */
+	350,			/* 8G */
+	0,			/* TODO: placeholder for 16-Mbit dev width */
+	0,			/* TODO: placeholder for 32-Mbit dev width */
+	0,			/* TODO: placeholder for 12-Mbit dev width */
+	0			/* TODO: placeholder for 24-Mbit dev width */
 };
 
 u32 speed_bin_table_t_rc[] = {
@@ -234,7 +247,7 @@ u32 speed_bin_table_t_rc[] = {
 	43285,
 	44220,
 	45155,
-	46900
+	46090
 };
 
 u32 speed_bin_table_t_rcd_t_rp[] = {
@@ -256,7 +269,7 @@ u32 speed_bin_table_t_rcd_t_rp[] = {
 	12840,
 	13910,
 	10285,
-	11022,
+	11220,
 	12155,
 	13090,
 };
@@ -357,13 +370,13 @@ u32 speed_bin_table(u8 index, enum speed_bin_table_elements element)
 		result = speed_bin_table_t_rcd_t_rp[index];
 		break;
 	case SPEED_BIN_TRAS:
-		if (index < 6)
+		if (index < SPEED_BIN_DDR_1066G)
 			result = 37500;
-		else if (index < 10)
+		else if (index < SPEED_BIN_DDR_1333J)
 			result = 36000;
-		else if (index < 14)
+		else if (index < SPEED_BIN_DDR_1600K)
 			result = 35000;
-		else if (index < 18)
+		else if (index < SPEED_BIN_DDR_1866M)
 			result = 34000;
 		else
 			result = 33000;
@@ -372,49 +385,49 @@ u32 speed_bin_table(u8 index, enum speed_bin_table_elements element)
 		result = speed_bin_table_t_rc[index];
 		break;
 	case SPEED_BIN_TRRD1K:
-		if (index < 3)
+		if (index < SPEED_BIN_DDR_800E)
 			result = 10000;
-		else if (index < 6)
-			result = 7005;
-		else if (index < 14)
+		else if (index < SPEED_BIN_DDR_1066G)
+			result = 7500;
+		else if (index < SPEED_BIN_DDR_1600K)
 			result = 6000;
 		else
 			result = 5000;
 		break;
 	case SPEED_BIN_TRRD2K:
-		if (index < 6)
+		if (index < SPEED_BIN_DDR_1066G)
 			result = 10000;
-		else if (index < 14)
-			result = 7005;
+		else if (index < SPEED_BIN_DDR_1600K)
+			result = 7500;
 		else
 			result = 6000;
 		break;
 	case SPEED_BIN_TPD:
-		if (index < 3)
+		if (index < SPEED_BIN_DDR_800E)
 			result = 7500;
-		else if (index < 10)
+		else if (index < SPEED_BIN_DDR_1333J)
 			result = 5625;
 		else
 			result = 5000;
 		break;
 	case SPEED_BIN_TFAW1K:
-		if (index < 3)
+		if (index < SPEED_BIN_DDR_800E)
 			result = 40000;
-		else if (index < 6)
+		else if (index < SPEED_BIN_DDR_1066G)
 			result = 37500;
-		else if (index < 14)
+		else if (index < SPEED_BIN_DDR_1600K)
 			result = 30000;
-		else if (index < 18)
+		else if (index < SPEED_BIN_DDR_1866M)
 			result = 27000;
 		else
 			result = 25000;
 		break;
 	case SPEED_BIN_TFAW2K:
-		if (index < 6)
+		if (index < SPEED_BIN_DDR_1066G)
 			result = 50000;
-		else if (index < 10)
+		else if (index < SPEED_BIN_DDR_1333J)
 			result = 45000;
-		else if (index < 14)
+		else if (index < SPEED_BIN_DDR_1600K)
 			result = 40000;
 		else
 			result = 35000;
@@ -466,14 +479,7 @@ static inline u32 pattern_table_get_killer_word16(u8 dqs, u8 index)
 			(PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) :
 			(PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM);
 		byte0 |= pattern_killer_pattern_table_map[index * 2][role] << i;
-	}
-
-	for (i = 0; i < 8; i++) {
-		role = (i == dqs) ?
-			(PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) :
-			(PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM);
-		byte1 |= pattern_killer_pattern_table_map
-			[index * 2 + 1][role] << i;
+		byte1 |= pattern_killer_pattern_table_map[index * 2 + 1][role] << i;
 	}
 
 	return byte0 | (byte0 << 8) | (byte1 << 16) | (byte1 << 24);
@@ -489,6 +495,79 @@ static inline u32 pattern_table_get_sso_word(u8 sso, u8 index)
 		return 0xffffffff;
 }
 
+static inline u32 pattern_table_get_sso_full_xtalk_word(u8 bit, u8 index)
+{
+	u8 byte = (1 << bit);
+
+	if ((index & 1) == 1)
+		byte = ~byte;
+
+	return byte | (byte << 8) | (byte << 16) | (byte << 24);
+
+}
+
+static inline u32 pattern_table_get_sso_xtalk_free_word(u8 bit, u8 index)
+{
+	u8 byte = (1 << bit);
+
+	if ((index & 1) == 1)
+		byte = 0;
+
+	return byte | (byte << 8) | (byte << 16) | (byte << 24);
+}
+
+static inline u32 pattern_table_get_isi_word(u8 index)
+{
+	u8 i0 = index % 32;
+	u8 i1 = index % 8;
+	u32 word;
+
+	if (i0 > 15)
+		word = ((i1 == 5) | (i1 == 7)) ? 0xffffffff : 0x0;
+	else
+		word = (i1 == 6) ? 0xffffffff : 0x0;
+
+	word = ((i0 % 16) > 7) ? ~word : word;
+
+	return word;
+}
+
+static inline u32 pattern_table_get_sso_full_xtalk_word16(u8 bit, u8 index)
+{
+	u8 byte = (1 << bit);
+
+	if ((index & 1) == 1)
+		byte = ~byte;
+
+	return byte | (byte << 8) | ((~byte) << 16) | ((~byte) << 24);
+}
+
+static inline u32 pattern_table_get_sso_xtalk_free_word16(u8 bit, u8 index)
+{
+	u8 byte = (1 << bit);
+
+	if ((index & 1) == 0)
+		return (byte << 16) | (byte << 24);
+	else
+		return byte | (byte << 8);
+}
+
+static inline u32 pattern_table_get_isi_word16(u8 index)
+{
+	u8 i0 = index % 16;
+	u8 i1 = index % 4;
+	u32 word;
+
+	if (i0 > 7)
+		word = (i1 > 1) ? 0x0000ffff : 0x0;
+	else
+		word = (i1 == 3) ? 0xffff0000 : 0x0;
+
+	word = ((i0 % 8) > 3) ? ~word : word;
+
+	return word;
+}
+
 static inline u32 pattern_table_get_vref_word(u8 index)
 {
 	if (0 == ((pattern_vref_pattern_table_map[index / 8] >>
@@ -528,13 +607,13 @@ static inline u32 pattern_table_get_static_pbs_word(u8 index)
 	return temp | (temp << 8) | (temp << 16) | (temp << 24);
 }
 
-inline u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
+u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
 {
 	u32 pattern;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask) == 0) {
-		/* 32bit patterns */
+		/* 32/64-bit patterns */
 		switch (type) {
 		case PATTERN_PBS1:
 		case PATTERN_PBS2:
@@ -578,9 +657,9 @@ inline u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
 			break;
 		case PATTERN_TEST:
 			if (index > 1 && index < 6)
-				pattern = PATTERN_20;
-			else
 				pattern = PATTERN_00;
+			else
+				pattern = PATTERN_FF;
 			break;
 		case PATTERN_FULL_SSO0:
 		case PATTERN_FULL_SSO1:
@@ -592,7 +671,34 @@ inline u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
 		case PATTERN_VREF:
 			pattern = pattern_table_get_vref_word(index);
 			break;
+		case PATTERN_SSO_FULL_XTALK_DQ0:
+		case PATTERN_SSO_FULL_XTALK_DQ1:
+		case PATTERN_SSO_FULL_XTALK_DQ2:
+		case PATTERN_SSO_FULL_XTALK_DQ3:
+		case PATTERN_SSO_FULL_XTALK_DQ4:
+		case PATTERN_SSO_FULL_XTALK_DQ5:
+		case PATTERN_SSO_FULL_XTALK_DQ6:
+		case PATTERN_SSO_FULL_XTALK_DQ7:
+			pattern = pattern_table_get_sso_full_xtalk_word(
+				(u8)(type - PATTERN_SSO_FULL_XTALK_DQ0), index);
+			break;
+		case PATTERN_SSO_XTALK_FREE_DQ0:
+		case PATTERN_SSO_XTALK_FREE_DQ1:
+		case PATTERN_SSO_XTALK_FREE_DQ2:
+		case PATTERN_SSO_XTALK_FREE_DQ3:
+		case PATTERN_SSO_XTALK_FREE_DQ4:
+		case PATTERN_SSO_XTALK_FREE_DQ5:
+		case PATTERN_SSO_XTALK_FREE_DQ6:
+		case PATTERN_SSO_XTALK_FREE_DQ7:
+			pattern = pattern_table_get_sso_xtalk_free_word(
+				(u8)(type - PATTERN_SSO_XTALK_FREE_DQ0), index);
+			break;
+		case PATTERN_ISI_XTALK_FREE:
+			pattern = pattern_table_get_isi_word(index);
+			break;
 		default:
+			DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("Error: %s: pattern type [%d] not supported\n",
+							      __func__, (int)type));
 			pattern = 0;
 			break;
 		}
@@ -631,7 +737,10 @@ inline u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
 				pattern = PATTERN_01;
 			break;
 		case PATTERN_TEST:
-			pattern = PATTERN_0080;
+			if ((index == 0) || (index == 3))
+				pattern = 0x00000000;
+			else
+				pattern = 0xFFFFFFFF;
 			break;
 		case PATTERN_FULL_SSO0:
 			pattern = 0x0000ffff;
@@ -645,7 +754,34 @@ inline u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
 		case PATTERN_VREF:
 			pattern = pattern_table_get_vref_word16(index);
 			break;
+		case PATTERN_SSO_FULL_XTALK_DQ0:
+		case PATTERN_SSO_FULL_XTALK_DQ1:
+		case PATTERN_SSO_FULL_XTALK_DQ2:
+		case PATTERN_SSO_FULL_XTALK_DQ3:
+		case PATTERN_SSO_FULL_XTALK_DQ4:
+		case PATTERN_SSO_FULL_XTALK_DQ5:
+		case PATTERN_SSO_FULL_XTALK_DQ6:
+		case PATTERN_SSO_FULL_XTALK_DQ7:
+			pattern = pattern_table_get_sso_full_xtalk_word16(
+				(u8)(type - PATTERN_SSO_FULL_XTALK_DQ0), index);
+			break;
+		case PATTERN_SSO_XTALK_FREE_DQ0:
+		case PATTERN_SSO_XTALK_FREE_DQ1:
+		case PATTERN_SSO_XTALK_FREE_DQ2:
+		case PATTERN_SSO_XTALK_FREE_DQ3:
+		case PATTERN_SSO_XTALK_FREE_DQ4:
+		case PATTERN_SSO_XTALK_FREE_DQ5:
+		case PATTERN_SSO_XTALK_FREE_DQ6:
+		case PATTERN_SSO_XTALK_FREE_DQ7:
+			pattern = pattern_table_get_sso_xtalk_free_word16(
+				(u8)(type - PATTERN_SSO_XTALK_FREE_DQ0), index);
+			break;
+		case PATTERN_ISI_XTALK_FREE:
+			pattern = pattern_table_get_isi_word16(index);
+			break;
 		default:
+			DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("Error: %s: pattern type [%d] not supported\n",
+							      __func__, (int)type));
 			pattern = 0;
 			break;
 		}
@@ -653,3 +789,30 @@ inline u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
 
 	return pattern;
 }
+
+/* Device attribute functions */
+void ddr3_tip_dev_attr_init(u32 dev_num)
+{
+	u32 attr_id;
+
+	for (attr_id = 0; attr_id < MV_ATTR_LAST; attr_id++)
+		ddr_dev_attributes[dev_num][attr_id] = 0xFF;
+
+	ddr_dev_attr_init_done[dev_num] = 1;
+}
+
+u32 ddr3_tip_dev_attr_get(u32 dev_num, enum mv_ddr_dev_attribute attr_id)
+{
+	if (ddr_dev_attr_init_done[dev_num] == 0)
+		ddr3_tip_dev_attr_init(dev_num);
+
+	return ddr_dev_attributes[dev_num][attr_id];
+}
+
+void ddr3_tip_dev_attr_set(u32 dev_num, enum mv_ddr_dev_attribute attr_id, u32 value)
+{
+	if (ddr_dev_attr_init_done[dev_num] == 0)
+		ddr3_tip_dev_attr_init(dev_num);
+
+	ddr_dev_attributes[dev_num][attr_id] = value;
+}
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_hw_algo.c b/drivers/ddr/marvell/a38x/ddr3_training_hw_algo.c
index 1fc173b60020..01da98399ae3 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training_hw_algo.c
+++ b/drivers/ddr/marvell/a38x/ddr3_training_hw_algo.c
@@ -4,12 +4,6 @@
  * SPDX-License-Identifier:	GPL-2.0
  */
 
-#include <common.h>
-#include <spl.h>
-#include <asm/io.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/soc.h>
-
 #include "ddr3_init.h"
 
 #define VREF_INITIAL_STEP		3
@@ -17,9 +11,8 @@
 #define VREF_MAX_INDEX			7
 #define MAX_VALUE			(1024 - 1)
 #define MIN_VALUE			(-MAX_VALUE)
-#define GET_RD_SAMPLE_DELAY(data, cs)	((data >> rd_sample_mask[cs]) & 0x1f)
+#define GET_RD_SAMPLE_DELAY(data, cs)	((data >> rd_sample_mask[cs]) & 0xf)
 
-u32 ck_delay = (u32)-1, ck_delay_16 = (u32)-1;
 u32 ca_delay;
 int ddr3_tip_centr_skip_min_win_check = 0;
 u8 current_vref[MAX_BUS_NUM][MAX_INTERFACE_NUM];
@@ -49,45 +42,41 @@ static u32 rd_sample_mask[] = {
  */
 int ddr3_tip_write_additional_odt_setting(u32 dev_num, u32 if_id)
 {
-	u32 cs_num = 0, max_cs = 0, max_read_sample = 0, min_read_sample = 0x1f;
+	u32 cs_num = 0, max_read_sample = 0, min_read_sample = 0x1f;
 	u32 data_read[MAX_INTERFACE_NUM] = { 0 };
 	u32 read_sample[MAX_CS_NUM];
 	u32 val;
 	u32 pup_index;
 	int max_phase = MIN_VALUE, current_phase;
 	enum hws_access_type access_type = ACCESS_TYPE_UNICAST;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
 
 	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
-				       DUNIT_ODT_CONTROL_REG,
+				       DUNIT_ODT_CTRL_REG,
 				       0 << 8, 0x3 << 8));
 	CHECK_STATUS(ddr3_tip_if_read(dev_num, access_type, if_id,
-				      READ_DATA_SAMPLE_DELAY,
+				      RD_DATA_SMPL_DLYS_REG,
 				      data_read, MASK_ALL_BITS));
 	val = data_read[if_id];
 
-	max_cs = hws_ddr3_tip_max_cs_get();
-
-	for (cs_num = 0; cs_num < max_cs; cs_num++) {
+	for (cs_num = 0; cs_num < MAX_CS_NUM; cs_num++) {
 		read_sample[cs_num] = GET_RD_SAMPLE_DELAY(val, cs_num);
 
 		/* find maximum of read_samples */
 		if (read_sample[cs_num] >= max_read_sample) {
-			if (read_sample[cs_num] == max_read_sample) {
-				/* search for max phase */;
-			} else {
-				max_read_sample = read_sample[cs_num];
+			if (read_sample[cs_num] == max_read_sample)
 				max_phase = MIN_VALUE;
-			}
+			else
+				max_read_sample = read_sample[cs_num];
 
 			for (pup_index = 0;
-			     pup_index < tm->num_of_bus_per_interface;
+			     pup_index < octets_per_if_num;
 			     pup_index++) {
 				CHECK_STATUS(ddr3_tip_bus_read
 					     (dev_num, if_id,
 					      ACCESS_TYPE_UNICAST, pup_index,
 					      DDR_PHY_DATA,
-					      RL_PHY_REG + CS_REG_VALUE(cs_num),
+					      RL_PHY_REG(cs_num),
 					      &val));
 
 				current_phase = ((int)val & 0xe0) >> 6;
@@ -101,21 +90,19 @@ int ddr3_tip_write_additional_odt_setting(u32 dev_num, u32 if_id)
 			min_read_sample = read_sample[cs_num];
 	}
 
-	if (min_read_sample <= tm->interface_params[if_id].cas_l) {
-		min_read_sample = (int)tm->interface_params[if_id].cas_l;
-	}
-
 	min_read_sample = min_read_sample - 1;
 	max_read_sample = max_read_sample + 4 + (max_phase + 1) / 2 + 1;
+	if (min_read_sample >= 0xf)
+		min_read_sample = 0xf;
 	if (max_read_sample >= 0x1f)
 		max_read_sample = 0x1f;
 
 	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
-				       ODT_TIMING_LOW,
+				       DDR_ODT_TIMING_LOW_REG,
 				       ((min_read_sample - 1) << 12),
 				       0xf << 12));
 	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
-				       ODT_TIMING_LOW,
+				       DDR_ODT_TIMING_LOW_REG,
 				       (max_read_sample << 16),
 				       0x1f << 16));
 
@@ -124,7 +111,7 @@ int ddr3_tip_write_additional_odt_setting(u32 dev_num, u32 if_id)
 
 int get_valid_win_rx(u32 dev_num, u32 if_id, u8 res[4])
 {
-	u32 reg_pup = RESULT_DB_PHY_REG_ADDR;
+	u32 reg_pup = RESULT_PHY_REG;
 	u32 reg_data;
 	u32 cs_num;
 	int i;
@@ -139,7 +126,7 @@ int get_valid_win_rx(u32 dev_num, u32 if_id, u8 res[4])
 					       ACCESS_TYPE_UNICAST, i,
 					       DDR_PHY_DATA, reg_pup,
 					       &reg_data));
-		res[i] = (reg_data >> RESULT_DB_PHY_REG_RX_OFFSET) & 0x1f;
+		res[i] = (reg_data >> RESULT_PHY_RX_OFFS) & 0x1f;
 	}
 
 	return 0;
@@ -177,7 +164,8 @@ int ddr3_tip_vref(u32 dev_num)
 	u32 copy_start_pattern, copy_end_pattern;
 	enum hws_result *flow_result = ddr3_tip_get_result_ptr(training_stage);
 	u8 res[4];
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	CHECK_STATUS(ddr3_tip_special_rx(dev_num));
 
@@ -191,9 +179,9 @@ int ddr3_tip_vref(u32 dev_num)
 
 	/* init params */
 	for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		for (pup = 0;
-		     pup < tm->num_of_bus_per_interface; pup++) {
+		     pup < octets_per_if_num; pup++) {
 			current_vref[pup][if_id] = 0;
 			last_vref[pup][if_id] = 0;
 			lim_vref[pup][if_id] = 0;
@@ -229,7 +217,7 @@ int ddr3_tip_vref(u32 dev_num)
 	}
 
 	/* TODO: Set number of active interfaces */
-	num_pup = tm->num_of_bus_per_interface * MAX_INTERFACE_NUM;
+	num_pup = octets_per_if_num * MAX_INTERFACE_NUM;
 
 	while ((algo_run_flag <= num_pup) & (while_count < 10)) {
 		while_count++;
@@ -240,13 +228,13 @@ int ddr3_tip_vref(u32 dev_num)
 
 			/* Read Valid window results only for non converge pups */
 			for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
-				VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+				VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 				if (interface_state[if_id] != 4) {
 					get_valid_win_rx(dev_num, if_id, res);
 					for (pup = 0;
-					     pup < tm->num_of_bus_per_interface;
+					     pup < octets_per_if_num;
 					     pup++) {
-						VALIDATE_ACTIVE
+						VALIDATE_BUS_ACTIVE
 							(tm->bus_act_mask, pup);
 						if (pup_st[pup]
 						    [if_id] ==
@@ -264,14 +252,14 @@ int ddr3_tip_vref(u32 dev_num)
 		}
 
 		for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 			DEBUG_TRAINING_HW_ALG(
 				DEBUG_LEVEL_TRACE,
 				("current_valid_window: IF[ %d ] - ", if_id));
 
 			for (pup = 0;
-			     pup < tm->num_of_bus_per_interface; pup++) {
-				VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+			     pup < octets_per_if_num; pup++) {
+				VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup);
 				DEBUG_TRAINING_HW_ALG(DEBUG_LEVEL_TRACE,
 						      ("%d ",
 						       current_valid_window
@@ -282,10 +270,10 @@ int ddr3_tip_vref(u32 dev_num)
 
 		/* Compare results and respond as function of state */
 		for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 			for (pup = 0;
-			     pup < tm->num_of_bus_per_interface; pup++) {
-				VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+			     pup < octets_per_if_num; pup++) {
+				VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup);
 				DEBUG_TRAINING_HW_ALG(DEBUG_LEVEL_TRACE,
 						      ("I/F[ %d ], pup[ %d ] STATE #%d (%d)\n",
 						       if_id, pup,
@@ -610,10 +598,10 @@ int ddr3_tip_vref(u32 dev_num)
 	}
 
 	for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		for (pup = 0;
-		     pup < tm->num_of_bus_per_interface; pup++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+		     pup < octets_per_if_num; pup++) {
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup);
 			CHECK_STATUS(ddr3_tip_bus_read
 				     (dev_num, if_id,
 				      ACCESS_TYPE_UNICAST, pup,
@@ -641,7 +629,7 @@ int ddr3_tip_cmd_addr_init_delay(u32 dev_num, u32 adll_tap)
 {
 	u32 if_id = 0;
 	u32 ck_num_adll_tap = 0, ca_num_adll_tap = 0, data = 0;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	/*
 	 * ck_delay_table is delaying the of the clock signal only.
@@ -654,22 +642,18 @@ int ddr3_tip_cmd_addr_init_delay(u32 dev_num, u32 adll_tap)
 	 */
 
 	/* Calc ADLL Tap */
-	if ((ck_delay == -1) || (ck_delay_16 == -1)) {
+	if (ck_delay == PARAM_UNDEFINED)
 		DEBUG_TRAINING_HW_ALG(
 			DEBUG_LEVEL_ERROR,
-			("ERROR: One of ck_delay values not initialized!!!\n"));
-	}
+			("ERROR: ck_delay is not initialized!\n"));
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-		/* Calc delay ps in ADLL tap */
-		if (tm->interface_params[if_id].bus_width ==
-		    BUS_WIDTH_16)
-			ck_num_adll_tap = ck_delay_16 / adll_tap;
-		else
-			ck_num_adll_tap = ck_delay / adll_tap;
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 
+		/* Calc delay ps in ADLL tap */
+		ck_num_adll_tap = ck_delay / adll_tap;
 		ca_num_adll_tap = ca_delay / adll_tap;
+
 		data = (ck_num_adll_tap & 0x3f) +
 			((ca_num_adll_tap & 0x3f) << 10);
 
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip.h b/drivers/ddr/marvell/a38x/ddr3_training_ip.h
index ed92873697e3..a14ce63eef32 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training_ip.h
+++ b/drivers/ddr/marvell/a38x/ddr3_training_ip.h
@@ -11,11 +11,10 @@
 #include "ddr_topology_def.h"
 #include "ddr_training_ip_db.h"
 
-#define DDR3_TIP_VERSION_STRING "DDR3 Training Sequence - Ver TIP-1.29."
-
 #define MAX_CS_NUM		4
 #define MAX_TOTAL_BUS_NUM	(MAX_INTERFACE_NUM * MAX_BUS_NUM)
-#define MAX_DQ_NUM		40
+#define TIP_ENG_LOCK	0x02000000
+#define TIP_TX_DLL_RANGE_MAX	64
 
 #define GET_MIN(arg1, arg2)	((arg1) < (arg2)) ? (arg1) : (arg2)
 #define GET_MAX(arg1, arg2)	((arg1) < (arg2)) ? (arg2) : (arg1)
@@ -39,11 +38,15 @@
 #define READ_LEVELING_TF_MASK_BIT	0x00010000
 #define WRITE_LEVELING_SUPP_TF_MASK_BIT	0x00020000
 #define DM_PBS_TX_MASK_BIT		0x00040000
+#define RL_DQS_BURST_MASK_BIT		0x00080000
 #define CENTRALIZATION_RX_MASK_BIT	0x00100000
 #define CENTRALIZATION_TX_MASK_BIT	0x00200000
 #define TX_EMPHASIS_MASK_BIT		0x00400000
 #define PER_BIT_READ_LEVELING_TF_MASK_BIT	0x00800000
 #define VREF_CALIBRATION_MASK_BIT	0x01000000
+#define WRITE_LEVELING_LF_MASK_BIT	0x02000000
+
+/* DDR4 Specific Training Mask bits */
 
 enum hws_result {
 	TEST_FAILED = 0,
@@ -80,6 +83,7 @@ enum auto_tune_stage {
 	TX_EMPHASIS,
 	LOAD_PATTERN_HIGH,
 	PER_BIT_READ_LEVELING_TF,
+	WRITE_LEVELING_LF,
 	MAX_STAGE_LIMIT
 };
 
@@ -111,7 +115,7 @@ struct pattern_info {
 
 /* CL value for each frequency */
 struct cl_val_per_freq {
-	u8 cl_val[DDR_FREQ_LIMIT];
+	u8 cl_val[DDR_FREQ_LAST];
 };
 
 struct cs_element {
@@ -168,11 +172,14 @@ int hws_ddr3_tip_select_ddr_controller(u32 dev_num, int enable);
 int hws_ddr3_tip_init_controller(u32 dev_num,
 				 struct init_cntr_param *init_cntr_prm);
 int hws_ddr3_tip_load_topology_map(u32 dev_num,
-				   struct hws_topology_map *topology);
+				   struct mv_ddr_topology_map *topology);
 int hws_ddr3_tip_run_alg(u32 dev_num, enum hws_algo_type algo_type);
 int hws_ddr3_tip_mode_read(u32 dev_num, struct mode_info *mode_info);
+int hws_ddr3_tip_read_training_result(u32 dev_num,
+		enum hws_result result[MAX_STAGE_LIMIT][MAX_INTERFACE_NUM]);
 int ddr3_tip_is_pup_lock(u32 *pup_buf, enum hws_training_result read_mode);
 u8 ddr3_tip_get_buf_min(u8 *buf_ptr);
 u8 ddr3_tip_get_buf_max(u8 *buf_ptr);
-
+uint64_t mv_ddr_get_memory_size_per_cs_in_bits(void);
+uint64_t mv_ddr_get_total_memory_size_in_bits(void);
 #endif /* _DDR3_TRAINING_IP_H_ */
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip_bist.h b/drivers/ddr/marvell/a38x/ddr3_training_ip_bist.h
index 5c9bfe98a096..856b49839465 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training_ip_bist.h
+++ b/drivers/ddr/marvell/a38x/ddr3_training_ip_bist.h
@@ -46,9 +46,13 @@ int hws_ddr3_run_bist(u32 dev_num, enum hws_pattern pattern, u32 *result,
 		      u32 cs_num);
 int ddr3_tip_run_sweep_test(int dev_num, u32 repeat_num, u32 direction,
 			    u32 mode);
+int ddr3_tip_run_leveling_sweep_test(int dev_num, u32 repeat_num,
+				     u32 direction, u32 mode);
 int ddr3_tip_print_regs(u32 dev_num);
 int ddr3_tip_reg_dump(u32 dev_num);
 int run_xsb_test(u32 dev_num, u32 mem_addr, u32 write_type, u32 read_type,
 		 u32 burst_length);
-
+int mv_ddr_dm_to_dq_diff_get(u8 adll_byte_high, u8 adll_byte_low, u8 *vw_vector,
+			     int *delta_h_adll, int *delta_l_adll);
+int mv_ddr_dm_vw_get(enum hws_pattern pattern, u32 cs, u8 *vw_vector);
 #endif /* _DDR3_TRAINING_IP_BIST_H_ */
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip_db.h b/drivers/ddr/marvell/a38x/ddr3_training_ip_db.h
index c0afa7742e94..55ae907ecb78 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training_ip_db.h
+++ b/drivers/ddr/marvell/a38x/ddr3_training_ip_db.h
@@ -10,7 +10,10 @@
 enum hws_pattern {
 	PATTERN_PBS1,
 	PATTERN_PBS2,
+	PATTERN_PBS3,
+	PATTERN_TEST,
 	PATTERN_RL,
+	PATTERN_RL2,
 	PATTERN_STATIC_PBS,
 	PATTERN_KILLER_DQ0,
 	PATTERN_KILLER_DQ1,
@@ -20,15 +23,73 @@ enum hws_pattern {
 	PATTERN_KILLER_DQ5,
 	PATTERN_KILLER_DQ6,
 	PATTERN_KILLER_DQ7,
-	PATTERN_PBS3,
-	PATTERN_RL2,
-	PATTERN_TEST,
+	PATTERN_VREF,
 	PATTERN_FULL_SSO0,
 	PATTERN_FULL_SSO1,
 	PATTERN_FULL_SSO2,
 	PATTERN_FULL_SSO3,
-	PATTERN_VREF,
-	PATTERN_LIMIT
+	PATTERN_LAST,
+	PATTERN_SSO_FULL_XTALK_DQ0,
+	PATTERN_SSO_FULL_XTALK_DQ1,
+	PATTERN_SSO_FULL_XTALK_DQ2,
+	PATTERN_SSO_FULL_XTALK_DQ3,
+	PATTERN_SSO_FULL_XTALK_DQ4,
+	PATTERN_SSO_FULL_XTALK_DQ5,
+	PATTERN_SSO_FULL_XTALK_DQ6,
+	PATTERN_SSO_FULL_XTALK_DQ7,
+	PATTERN_SSO_XTALK_FREE_DQ0,
+	PATTERN_SSO_XTALK_FREE_DQ1,
+	PATTERN_SSO_XTALK_FREE_DQ2,
+	PATTERN_SSO_XTALK_FREE_DQ3,
+	PATTERN_SSO_XTALK_FREE_DQ4,
+	PATTERN_SSO_XTALK_FREE_DQ5,
+	PATTERN_SSO_XTALK_FREE_DQ6,
+	PATTERN_SSO_XTALK_FREE_DQ7,
+	PATTERN_ISI_XTALK_FREE
 };
 
+enum mv_wl_supp_mode {
+	WRITE_LEVELING_SUPP_REG_MODE,
+	WRITE_LEVELING_SUPP_ECC_MODE_DATA_PUPS,
+	WRITE_LEVELING_SUPP_ECC_MODE_ECC_PUP4,
+	WRITE_LEVELING_SUPP_ECC_MODE_ECC_PUP3,
+	WRITE_LEVELING_SUPP_ECC_MODE_ECC_PUP8
+};
+
+enum mv_ddr_dev_attribute {
+	MV_ATTR_TIP_REV,
+	MV_ATTR_PHY_EDGE,
+	MV_ATTR_OCTET_PER_INTERFACE,
+	MV_ATTR_PLL_BEFORE_INIT,
+	MV_ATTR_TUNE_MASK,
+	MV_ATTR_INIT_FREQ,
+	MV_ATTR_MID_FREQ,
+	MV_ATTR_DFS_LOW_FREQ,
+	MV_ATTR_DFS_LOW_PHY,
+	MV_ATTR_DELAY_ENABLE,
+	MV_ATTR_CK_DELAY,
+	MV_ATTR_CA_DELAY,
+	MV_ATTR_INTERLEAVE_WA,
+	MV_ATTR_LAST
+};
+
+enum mv_ddr_tip_revison {
+	MV_TIP_REV_NA,
+	MV_TIP_REV_1, /* NP5 */
+	MV_TIP_REV_2, /* BC2 */
+	MV_TIP_REV_3, /* AC3 */
+	MV_TIP_REV_4, /* A-380/A-390 */
+	MV_TIP_REV_LAST
+};
+
+enum mv_ddr_phy_edge {
+	MV_DDR_PHY_EDGE_POSITIVE,
+	MV_DDR_PHY_EDGE_NEGATIVE
+};
+
+/* Device attribute functions */
+void ddr3_tip_dev_attr_init(u32 dev_num);
+u32 ddr3_tip_dev_attr_get(u32 dev_num, enum mv_ddr_dev_attribute attr_id);
+void ddr3_tip_dev_attr_set(u32 dev_num, enum mv_ddr_dev_attribute attr_id, u32 value);
+
 #endif /* _DDR3_TRAINING_IP_DB_H_ */
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip_def.h b/drivers/ddr/marvell/a38x/ddr3_training_ip_def.h
index 51a66d8491a2..731d1e896bd4 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training_ip_def.h
+++ b/drivers/ddr/marvell/a38x/ddr3_training_ip_def.h
@@ -7,8 +7,6 @@
 #ifndef _DDR3_TRAINING_IP_DEF_H
 #define _DDR3_TRAINING_IP_DEF_H
 
-#include "silicon_if.h"
-
 #define PATTERN_55			0x55555555
 #define PATTERN_AA			0xaaaaaaaa
 #define PATTERN_80			0x80808080
@@ -36,6 +34,7 @@
 #define ADLL_RX_LENGTH			32
 
 #define PARAM_NOT_CARE			0
+#define PARAM_UNDEFINED			0xffffffff
 
 #define READ_LEVELING_PHY_OFFSET	2
 #define WRITE_LEVELING_PHY_OFFSET	0
@@ -100,6 +99,8 @@
 
 #define _1G				0x40000000
 #define _2G				0x80000000
+#define _4G				0x100000000
+#define _8G				0x200000000
 
 #define ADDR_SIZE_512MB			0x04000000
 #define ADDR_SIZE_1GB			0x08000000
@@ -164,10 +165,33 @@ enum hws_wl_supp {
 	ALIGN_SHIFT
 };
 
+enum  mv_ddr_tip_bit_state {
+	BIT_LOW_UI,
+	BIT_HIGH_UI,
+	BIT_SPLIT_IN,
+	BIT_SPLIT_OUT,
+	BIT_STATE_LAST
+};
+
+enum  mv_ddr_tip_byte_state{
+	BYTE_NOT_DEFINED,
+	BYTE_HOMOGENEOUS_LOW = 0x1,
+	BYTE_HOMOGENEOUS_HIGH = 0x2,
+	BYTE_HOMOGENEOUS_SPLIT_IN = 0x4,
+	BYTE_HOMOGENEOUS_SPLIT_OUT = 0x8,
+	BYTE_SPLIT_OUT_MIX = 0x10,
+	BYTE_STATE_LAST
+};
+
 struct reg_data {
-	u32 reg_addr;
-	u32 reg_data;
-	u32 reg_mask;
+	unsigned int reg_addr;
+	unsigned int reg_data;
+	unsigned int reg_mask;
+};
+
+enum dm_direction {
+	DM_DIR_INVERSE,
+	DM_DIR_DIRECT
 };
 
 #endif /* _DDR3_TRAINING_IP_DEF_H */
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c b/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c
index 011824ab42a1..855025953f4e 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c
+++ b/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c
@@ -4,12 +4,6 @@
  * SPDX-License-Identifier:	GPL-2.0
  */
 
-#include <common.h>
-#include <spl.h>
-#include <asm/io.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/soc.h>
-
 #include "ddr3_init.h"
 
 #define PATTERN_1	0x55555555
@@ -22,6 +16,7 @@ u32 phy_reg_bk[MAX_INTERFACE_NUM][MAX_BUS_NUM][BUS_WIDTH_IN_BITS];
 
 u32 training_res[MAX_INTERFACE_NUM * MAX_BUS_NUM * BUS_WIDTH_IN_BITS *
 		 HWS_SEARCH_DIR_LIMIT];
+u8 byte_status[MAX_INTERFACE_NUM][MAX_BUS_NUM];	/* holds the bit status in the byte in wrapper function*/
 
 u16 mask_results_dq_reg_map[] = {
 	RESULT_CONTROL_PUP_0_BIT_0_REG, RESULT_CONTROL_PUP_0_BIT_1_REG,
@@ -44,14 +39,39 @@ u16 mask_results_dq_reg_map[] = {
 	RESULT_CONTROL_PUP_4_BIT_2_REG, RESULT_CONTROL_PUP_4_BIT_3_REG,
 	RESULT_CONTROL_PUP_4_BIT_4_REG, RESULT_CONTROL_PUP_4_BIT_5_REG,
 	RESULT_CONTROL_PUP_4_BIT_6_REG, RESULT_CONTROL_PUP_4_BIT_7_REG,
+#if MAX_BUS_NUM == 9
+	RESULT_CONTROL_PUP_5_BIT_0_REG, RESULT_CONTROL_PUP_5_BIT_1_REG,
+	RESULT_CONTROL_PUP_5_BIT_2_REG, RESULT_CONTROL_PUP_5_BIT_3_REG,
+	RESULT_CONTROL_PUP_5_BIT_4_REG, RESULT_CONTROL_PUP_5_BIT_5_REG,
+	RESULT_CONTROL_PUP_5_BIT_6_REG, RESULT_CONTROL_PUP_5_BIT_7_REG,
+	RESULT_CONTROL_PUP_6_BIT_0_REG, RESULT_CONTROL_PUP_6_BIT_1_REG,
+	RESULT_CONTROL_PUP_6_BIT_2_REG, RESULT_CONTROL_PUP_6_BIT_3_REG,
+	RESULT_CONTROL_PUP_6_BIT_4_REG, RESULT_CONTROL_PUP_6_BIT_5_REG,
+	RESULT_CONTROL_PUP_6_BIT_6_REG, RESULT_CONTROL_PUP_6_BIT_7_REG,
+	RESULT_CONTROL_PUP_7_BIT_0_REG, RESULT_CONTROL_PUP_7_BIT_1_REG,
+	RESULT_CONTROL_PUP_7_BIT_2_REG, RESULT_CONTROL_PUP_7_BIT_3_REG,
+	RESULT_CONTROL_PUP_7_BIT_4_REG, RESULT_CONTROL_PUP_7_BIT_5_REG,
+	RESULT_CONTROL_PUP_7_BIT_6_REG, RESULT_CONTROL_PUP_7_BIT_7_REG,
+	RESULT_CONTROL_PUP_8_BIT_0_REG, RESULT_CONTROL_PUP_8_BIT_1_REG,
+	RESULT_CONTROL_PUP_8_BIT_2_REG, RESULT_CONTROL_PUP_8_BIT_3_REG,
+	RESULT_CONTROL_PUP_8_BIT_4_REG, RESULT_CONTROL_PUP_8_BIT_5_REG,
+	RESULT_CONTROL_PUP_8_BIT_6_REG, RESULT_CONTROL_PUP_8_BIT_7_REG,
+#endif
+	0xffff
 };
 
 u16 mask_results_pup_reg_map[] = {
 	RESULT_CONTROL_BYTE_PUP_0_REG, RESULT_CONTROL_BYTE_PUP_1_REG,
 	RESULT_CONTROL_BYTE_PUP_2_REG, RESULT_CONTROL_BYTE_PUP_3_REG,
-	RESULT_CONTROL_BYTE_PUP_4_REG
+	RESULT_CONTROL_BYTE_PUP_4_REG,
+#if MAX_BUS_NUM == 9
+	RESULT_CONTROL_BYTE_PUP_5_REG, RESULT_CONTROL_BYTE_PUP_6_REG,
+	RESULT_CONTROL_BYTE_PUP_7_REG, RESULT_CONTROL_BYTE_PUP_8_REG,
+#endif
+	0xffff
 };
 
+#if MAX_BUS_NUM == 5
 u16 mask_results_dq_reg_map_pup3_ecc[] = {
 	RESULT_CONTROL_PUP_0_BIT_0_REG, RESULT_CONTROL_PUP_0_BIT_1_REG,
 	RESULT_CONTROL_PUP_0_BIT_2_REG, RESULT_CONTROL_PUP_0_BIT_3_REG,
@@ -69,17 +89,120 @@ u16 mask_results_dq_reg_map_pup3_ecc[] = {
 	RESULT_CONTROL_PUP_4_BIT_2_REG, RESULT_CONTROL_PUP_4_BIT_3_REG,
 	RESULT_CONTROL_PUP_4_BIT_4_REG, RESULT_CONTROL_PUP_4_BIT_5_REG,
 	RESULT_CONTROL_PUP_4_BIT_6_REG, RESULT_CONTROL_PUP_4_BIT_7_REG,
-	RESULT_CONTROL_PUP_4_BIT_0_REG, RESULT_CONTROL_PUP_4_BIT_1_REG,
-	RESULT_CONTROL_PUP_4_BIT_2_REG, RESULT_CONTROL_PUP_4_BIT_3_REG,
-	RESULT_CONTROL_PUP_4_BIT_4_REG, RESULT_CONTROL_PUP_4_BIT_5_REG,
-	RESULT_CONTROL_PUP_4_BIT_6_REG, RESULT_CONTROL_PUP_4_BIT_7_REG,
+	RESULT_CONTROL_PUP_3_BIT_0_REG, RESULT_CONTROL_PUP_3_BIT_1_REG,
+	RESULT_CONTROL_PUP_3_BIT_2_REG, RESULT_CONTROL_PUP_3_BIT_3_REG,
+	RESULT_CONTROL_PUP_3_BIT_4_REG, RESULT_CONTROL_PUP_3_BIT_5_REG,
+	RESULT_CONTROL_PUP_3_BIT_6_REG, RESULT_CONTROL_PUP_3_BIT_7_REG
 };
+#endif
 
+#if MAX_BUS_NUM == 5
 u16 mask_results_pup_reg_map_pup3_ecc[] = {
 	RESULT_CONTROL_BYTE_PUP_0_REG, RESULT_CONTROL_BYTE_PUP_1_REG,
 	RESULT_CONTROL_BYTE_PUP_2_REG, RESULT_CONTROL_BYTE_PUP_4_REG,
 	RESULT_CONTROL_BYTE_PUP_4_REG
 };
+#endif
+
+struct pattern_info pattern_table_64[] = {
+	/*
+	 * num_of_phases_tx, tx_burst_size;
+	 * delay_between_bursts, num_of_phases_rx,
+	 * start_addr, pattern_len
+	 */
+	{0x7, 0x7, 2, 0x7, 0x00000, 8},		/* PATTERN_PBS1 */
+	{0x7, 0x7, 2, 0x7, 0x00080, 8},		/* PATTERN_PBS2 */
+	{0x7, 0x7, 2, 0x7, 0x00100, 8},		/* PATTERN_PBS3 */
+	{0x7, 0x7, 2, 0x7, 0x00030, 8},		/* PATTERN_TEST */
+	{0x7, 0x7, 2, 0x7, 0x00100, 8},		/* PATTERN_RL */
+	{0x7, 0x7, 2, 0x7, 0x00100, 8},		/* PATTERN_RL2 */
+	{0x1f, 0xf, 2, 0xf, 0x00680, 32},	/* PATTERN_STATIC_PBS */
+	{0x1f, 0xf, 2, 0xf, 0x00a80, 32},	/* PATTERN_KILLER_DQ0 */
+	{0x1f, 0xf, 2, 0xf, 0x01280, 32},	/* PATTERN_KILLER_DQ1 */
+	{0x1f, 0xf, 2, 0xf, 0x01a80, 32},	/* PATTERN_KILLER_DQ2 */
+	{0x1f, 0xf, 2, 0xf, 0x02280, 32},	/* PATTERN_KILLER_DQ3 */
+	{0x1f, 0xf, 2, 0xf, 0x02a80, 32},	/* PATTERN_KILLER_DQ4 */
+	{0x1f, 0xf, 2, 0xf, 0x03280, 32},	/* PATTERN_KILLER_DQ5 */
+	{0x1f, 0xf, 2, 0xf, 0x03a80, 32},	/* PATTERN_KILLER_DQ6 */
+	{0x1f, 0xf, 2, 0xf, 0x04280, 32},	/* PATTERN_KILLER_DQ7 */
+	{0x1f, 0xf, 2, 0xf, 0x00e80, 32},	/* PATTERN_KILLER_DQ0_64 */
+	{0x1f, 0xf, 2, 0xf, 0x01680, 32},	/* PATTERN_KILLER_DQ1_64 */
+	{0x1f, 0xf, 2, 0xf, 0x01e80, 32},	/* PATTERN_KILLER_DQ2_64 */
+	{0x1f, 0xf, 2, 0xf, 0x02680, 32},	/* PATTERN_KILLER_DQ3_64 */
+	{0x1f, 0xf, 2, 0xf, 0x02e80, 32},	/* PATTERN_KILLER_DQ4_64 */
+	{0x1f, 0xf, 2, 0xf, 0x03680, 32},	/* PATTERN_KILLER_DQ5_64 */
+	{0x1f, 0xf, 2, 0xf, 0x03e80, 32},	/* PATTERN_KILLER_DQ6_64 */
+	{0x1f, 0xf, 2, 0xf, 0x04680, 32},	/* PATTERN_KILLER_DQ7_64 */
+	{0x1f, 0xf, 2, 0xf, 0x04a80, 32},	/* PATTERN_KILLER_DQ0_INV */
+	{0x1f, 0xf, 2, 0xf, 0x05280, 32},	/* PATTERN_KILLER_DQ1_INV */
+	{0x1f, 0xf, 2, 0xf, 0x05a80, 32},	/* PATTERN_KILLER_DQ2_INV */
+	{0x1f, 0xf, 2, 0xf, 0x06280, 32},	/* PATTERN_KILLER_DQ3_INV */
+	{0x1f, 0xf, 2, 0xf, 0x06a80, 32},	/* PATTERN_KILLER_DQ4_INV */
+	{0x1f, 0xf, 2, 0xf, 0x07280, 32},	/* PATTERN_KILLER_DQ5_INV */
+	{0x1f, 0xf, 2, 0xf, 0x07a80, 32},	/* PATTERN_KILLER_DQ6_INV */
+	{0x1f, 0xf, 2, 0xf, 0x08280, 32},	/* PATTERN_KILLER_DQ7_INV */
+	{0x1f, 0xf, 2, 0xf, 0x04e80, 32},	/* PATTERN_KILLER_DQ0_INV_64 */
+	{0x1f, 0xf, 2, 0xf, 0x05680, 32},	/* PATTERN_KILLER_DQ1_INV_64 */
+	{0x1f, 0xf, 2, 0xf, 0x05e80, 32},	/* PATTERN_KILLER_DQ2_INV_64 */
+	{0x1f, 0xf, 2, 0xf, 0x06680, 32},	/* PATTERN_KILLER_DQ3_INV_64 */
+	{0x1f, 0xf, 2, 0xf, 0x06e80, 32},	/* PATTERN_KILLER_DQ4_INV_64 */
+	{0x1f, 0xf, 2, 0xf, 0x07680, 32},	/* PATTERN_KILLER_DQ5_INV_64 */
+	{0x1f, 0xf, 2, 0xf, 0x07e80, 32},	/* PATTERN_KILLER_DQ6_INV_64 */
+	{0x1f, 0xf, 2, 0xf, 0x08680, 32},	/* PATTERN_KILLER_DQ7_INV_64 */
+	{0x1f, 0xf, 2, 0xf, 0x08a80, 32},	/* PATTERN_SSO_FULL_XTALK_DQ0 */
+	{0x1f, 0xf, 2, 0xf, 0x09280, 32},	/* PATTERN_SSO_FULL_XTALK_DQ1 */
+	{0x1f, 0xf, 2, 0xf, 0x09a80, 32},	/* PATTERN_SSO_FULL_XTALK_DQ2 */
+	{0x1f, 0xf, 2, 0xf, 0x0a280, 32},	/* PATTERN_SSO_FULL_XTALK_DQ3 */
+	{0x1f, 0xf, 2, 0xf, 0x0aa80, 32},	/* PATTERN_SSO_FULL_XTALK_DQ4 */
+	{0x1f, 0xf, 2, 0xf, 0x0b280, 32},	/* PATTERN_SSO_FULL_XTALK_DQ5 */
+	{0x1f, 0xf, 2, 0xf, 0x0ba80, 32},	/* PATTERN_SSO_FULL_XTALK_DQ6 */
+	{0x1f, 0xf, 2, 0xf, 0x0c280, 32},	/* PATTERN_SSO_FULL_XTALK_DQ7 */
+	{0x1f, 0xf, 2, 0xf, 0x08e80, 32},	/* PATTERN_SSO_FULL_XTALK_DQ0_64 */
+	{0x1f, 0xf, 2, 0xf, 0x09680, 32},	/* PATTERN_SSO_FULL_XTALK_DQ1_64 */
+	{0x1f, 0xf, 2, 0xf, 0x09e80, 32},	/* PATTERN_SSO_FULL_XTALK_DQ2_64 */
+	{0x1f, 0xf, 2, 0xf, 0x0a680, 32},	/* PATTERN_SSO_FULL_XTALK_DQ3_64 */
+	{0x1f, 0xf, 2, 0xf, 0x0ae80, 32},	/* PATTERN_SSO_FULL_XTALK_DQ4_64 */
+	{0x1f, 0xf, 2, 0xf, 0x0b680, 32},	/* PATTERN_SSO_FULL_XTALK_DQ5_64 */
+	{0x1f, 0xf, 2, 0xf, 0x0be80, 32},	/* PATTERN_SSO_FULL_XTALK_DQ6_64 */
+	{0x1f, 0xf, 2, 0xf, 0x0c680, 32},	/* PATTERN_SSO_FULL_XTALK_DQ7_64 */
+	{0x1f, 0xf, 2, 0xf, 0x0ca80, 32},	/* PATTERN_SSO_XTALK_FREE_DQ0 */
+	{0x1f, 0xf, 2, 0xf, 0x0d280, 32},	/* PATTERN_SSO_XTALK_FREE_DQ1 */
+	{0x1f, 0xf, 2, 0xf, 0x0da80, 32},	/* PATTERN_SSO_XTALK_FREE_DQ2 */
+	{0x1f, 0xf, 2, 0xf, 0x0e280, 32},	/* PATTERN_SSO_XTALK_FREE_DQ3 */
+	{0x1f, 0xf, 2, 0xf, 0x0ea80, 32},	/* PATTERN_SSO_XTALK_FREE_DQ4 */
+	{0x1f, 0xf, 2, 0xf, 0x0f280, 32},	/* PATTERN_SSO_XTALK_FREE_DQ5 */
+	{0x1f, 0xf, 2, 0xf, 0x0fa80, 32},	/* PATTERN_SSO_XTALK_FREE_DQ6 */
+	{0x1f, 0xf, 2, 0xf, 0x10280, 32},	/* PATTERN_SSO_XTALK_FREE_DQ7 */
+	{0x1f, 0xf, 2, 0xf, 0x0ce80, 32},	/* PATTERN_SSO_XTALK_FREE_DQ0_64 */
+	{0x1f, 0xf, 2, 0xf, 0x0d680, 32},	/* PATTERN_SSO_XTALK_FREE_DQ1_64 */
+	{0x1f, 0xf, 2, 0xf, 0x0de80, 32},	/* PATTERN_SSO_XTALK_FREE_DQ2_64 */
+	{0x1f, 0xf, 2, 0xf, 0x0e680, 32},	/* PATTERN_SSO_XTALK_FREE_DQ3_64 */
+	{0x1f, 0xf, 2, 0xf, 0x0ee80, 32},	/* PATTERN_SSO_XTALK_FREE_DQ4_64 */
+	{0x1f, 0xf, 2, 0xf, 0x0f680, 32},	/* PATTERN_SSO_XTALK_FREE_DQ5_64 */
+	{0x1f, 0xf, 2, 0xf, 0x0fe80, 32},	/* PATTERN_SSO_XTALK_FREE_DQ6_64 */
+	{0x1f, 0xf, 2, 0xf, 0x10680, 32},	/* PATTERN_SSO_XTALK_FREE_DQ7_64 */
+	{0x1f, 0xf, 2, 0xf, 0x10a80, 32},	/* PATTERN_ISI_XTALK_FREE */
+	{0x1f, 0xf, 2, 0xf, 0x10e80, 32},	/* PATTERN_ISI_XTALK_FREE_64 */
+	{0x1f, 0xf, 2, 0xf, 0x11280, 32},	/* PATTERN_VREF */
+	{0x1f, 0xf, 2, 0xf, 0x11680, 32},	/* PATTERN_VREF_64 */
+	{0x1f, 0xf, 2, 0xf, 0x11a80, 32},	/* PATTERN_VREF_INV */
+	{0x1f, 0xf, 2, 0xf, 0x11e80, 32},	/* PATTERN_FULL_SSO_0T */
+	{0x1f, 0xf, 2, 0xf, 0x12280, 32},	/* PATTERN_FULL_SSO_1T */
+	{0x1f, 0xf, 2, 0xf, 0x12680, 32},	/* PATTERN_FULL_SSO_2T */
+	{0x1f, 0xf, 2, 0xf, 0x12a80, 32},	/* PATTERN_FULL_SSO_3T */
+	{0x1f, 0xf, 2, 0xf, 0x12e80, 32},	/* PATTERN_RESONANCE_1T */
+	{0x1f, 0xf, 2, 0xf, 0x13280, 32},	/* PATTERN_RESONANCE_2T */
+	{0x1f, 0xf, 2, 0xf, 0x13680, 32},	/* PATTERN_RESONANCE_3T */
+	{0x1f, 0xf, 2, 0xf, 0x13a80, 32},	/* PATTERN_RESONANCE_4T */
+	{0x1f, 0xf, 2, 0xf, 0x13e80, 32},	/* PATTERN_RESONANCE_5T */
+	{0x1f, 0xf, 2, 0xf, 0x14280, 32},	/* PATTERN_RESONANCE_6T */
+	{0x1f, 0xf, 2, 0xf, 0x14680, 32},	/* PATTERN_RESONANCE_7T */
+	{0x1f, 0xf, 2, 0xf, 0x14a80, 32},	/* PATTERN_RESONANCE_8T */
+	{0x1f, 0xf, 2, 0xf, 0x14e80, 32},	/* PATTERN_RESONANCE_9T */
+	{0x1f, 0xf, 2, 0xf, 0x15280, 32},	/* PATTERN_ZERO */
+	{0x1f, 0xf, 2, 0xf, 0x15680, 32}	/* PATTERN_ONE */
+	/* Note: actual start_address is "<< 3" of defined address */
+};
 
 struct pattern_info pattern_table_16[] = {
 	/*
@@ -88,7 +211,10 @@ struct pattern_info pattern_table_16[] = {
 	 */
 	{1, 1, 2, 1, 0x0080, 2},	/* PATTERN_PBS1 */
 	{1, 1, 2, 1, 0x00c0, 2},	/* PATTERN_PBS2 */
+	{1, 1, 2, 1, 0x0380, 2},	/* PATTERN_PBS3 */
+	{1, 1, 2, 1, 0x0040, 2},	/* PATTERN_TEST */
 	{1, 1, 2, 1, 0x0100, 2},	/* PATTERN_RL */
+	{1, 1, 2, 1, 0x0000, 2},	/* PATTERN_RL2 */
 	{0xf, 0x7, 2, 0x7, 0x0140, 16},	/* PATTERN_STATIC_PBS */
 	{0xf, 0x7, 2, 0x7, 0x0190, 16},	/* PATTERN_KILLER_DQ0 */
 	{0xf, 0x7, 2, 0x7, 0x01d0, 16},	/* PATTERN_KILLER_DQ1 */
@@ -98,15 +224,29 @@ struct pattern_info pattern_table_16[] = {
 	{0xf, 0x7, 2, 0x7, 0x02d0, 16},	/* PATTERN_KILLER_DQ5 */
 	{0xf, 0x7, 2, 0x7, 0x0310, 16},	/* PATTERN_KILLER_DQ6 */
 	{0xf, 0x7, 2, 0x7, 0x0350, 16},	/* PATTERN_KILLER_DQ7 */
-	{1, 1, 2, 1, 0x0380, 2},	/* PATTERN_PBS3 */
-	{1, 1, 2, 1, 0x0000, 2},	/* PATTERN_RL2 */
-	{1, 1, 2, 1, 0x0040, 2},	/* PATTERN_TEST */
+	{0xf, 0x7, 2, 0x7, 0x04c0, 16},	/* PATTERN_VREF */
 	{0xf, 0x7, 2, 0x7, 0x03c0, 16},	/* PATTERN_FULL_SSO_1T */
 	{0xf, 0x7, 2, 0x7, 0x0400, 16},	/* PATTERN_FULL_SSO_2T */
 	{0xf, 0x7, 2, 0x7, 0x0440, 16},	/* PATTERN_FULL_SSO_3T */
 	{0xf, 0x7, 2, 0x7, 0x0480, 16},	/* PATTERN_FULL_SSO_4T */
-	{0xf, 0x7, 2, 0x7, 0x04c0, 16}	/* PATTERN_VREF */
-	/*Note: actual start_address is <<3 of defined addess */
+	{0xf, 7, 2, 7, 0x6280, 16},	/* PATTERN_SSO_FULL_XTALK_DQ1 */
+	{0xf, 7, 2, 7, 0x6680, 16},	/* PATTERN_SSO_FULL_XTALK_DQ1 */
+	{0xf, 7, 2, 7, 0x6A80, 16},	/* PATTERN_SSO_FULL_XTALK_DQ2 */
+	{0xf, 7, 2, 7, 0x6E80, 16},	/* PATTERN_SSO_FULL_XTALK_DQ3 */
+	{0xf, 7, 2, 7, 0x7280, 16},	/* PATTERN_SSO_FULL_XTALK_DQ4 */
+	{0xf, 7, 2, 7, 0x7680, 16},	/* PATTERN_SSO_FULL_XTALK_DQ5 */
+	{0xf, 7, 2, 7, 0x7A80, 16},	/* PATTERN_SSO_FULL_XTALK_DQ6 */
+	{0xf, 7, 2, 7, 0x7E80, 16},	/* PATTERN_SSO_FULL_XTALK_DQ7 */
+	{0xf, 7, 2, 7, 0x8280, 16},	/* PATTERN_SSO_XTALK_FREE_DQ0 */
+	{0xf, 7, 2, 7, 0x8680, 16},	/* PATTERN_SSO_XTALK_FREE_DQ1 */
+	{0xf, 7, 2, 7, 0x8A80, 16},	/* PATTERN_SSO_XTALK_FREE_DQ2 */
+	{0xf, 7, 2, 7, 0x8E80, 16},	/* PATTERN_SSO_XTALK_FREE_DQ3 */
+	{0xf, 7, 2, 7, 0x9280, 16},	/* PATTERN_SSO_XTALK_FREE_DQ4 */
+	{0xf, 7, 2, 7, 0x9680, 16},	/* PATTERN_SSO_XTALK_FREE_DQ5 */
+	{0xf, 7, 2, 7, 0x9A80, 16},	/* PATTERN_SSO_XTALK_FREE_DQ6 */
+	{0xf, 7, 2, 7, 0x9E80, 16},	/* PATTERN_SSO_XTALK_FREE_DQ7 */
+	{0xf, 7, 2, 7, 0xA280, 16}	/* PATTERN_ISI_XTALK_FREE */
+	/* Note: actual start_address is "<< 3" of defined address */
 };
 
 struct pattern_info pattern_table_32[] = {
@@ -116,7 +256,10 @@ struct pattern_info pattern_table_32[] = {
 	 */
 	{3, 3, 2, 3, 0x0080, 4},	/* PATTERN_PBS1 */
 	{3, 3, 2, 3, 0x00c0, 4},	/* PATTERN_PBS2 */
+	{3, 3, 2, 3, 0x0380, 4},	/* PATTERN_PBS3 */
+	{3, 3, 2, 3, 0x0040, 4},	/* PATTERN_TEST */
 	{3, 3, 2, 3, 0x0100, 4},	/* PATTERN_RL */
+	{3, 3, 2, 3, 0x0000, 4},	/* PATTERN_RL2 */
 	{0x1f, 0xf, 2, 0xf, 0x0140, 32},	/* PATTERN_STATIC_PBS */
 	{0x1f, 0xf, 2, 0xf, 0x0190, 32},	/* PATTERN_KILLER_DQ0 */
 	{0x1f, 0xf, 2, 0xf, 0x01d0, 32},	/* PATTERN_KILLER_DQ1 */
@@ -126,15 +269,29 @@ struct pattern_info pattern_table_32[] = {
 	{0x1f, 0xf, 2, 0xf, 0x02d0, 32},	/* PATTERN_KILLER_DQ5 */
 	{0x1f, 0xf, 2, 0xf, 0x0310, 32},	/* PATTERN_KILLER_DQ6 */
 	{0x1f, 0xf, 2, 0xf, 0x0350, 32},	/* PATTERN_KILLER_DQ7 */
-	{3, 3, 2, 3, 0x0380, 4},	/* PATTERN_PBS3 */
-	{3, 3, 2, 3, 0x0000, 4},	/* PATTERN_RL2 */
-	{3, 3, 2, 3, 0x0040, 4},	/* PATTERN_TEST */
+	{0x1f, 0xf, 2, 0xf, 0x04c0, 32},	/* PATTERN_VREF */
 	{0x1f, 0xf, 2, 0xf, 0x03c0, 32},	/* PATTERN_FULL_SSO_1T */
 	{0x1f, 0xf, 2, 0xf, 0x0400, 32},	/* PATTERN_FULL_SSO_2T */
 	{0x1f, 0xf, 2, 0xf, 0x0440, 32},	/* PATTERN_FULL_SSO_3T */
 	{0x1f, 0xf, 2, 0xf, 0x0480, 32},	/* PATTERN_FULL_SSO_4T */
-	{0x1f, 0xf, 2, 0xf, 0x04c0, 32}	/* PATTERN_VREF */
-	/*Note: actual start_address is <<3 of defined addess */
+	{0x1f, 0xF, 2, 0xf, 0x6280, 32},	/* PATTERN_SSO_FULL_XTALK_DQ0 */
+	{0x1f, 0xF, 2, 0xf, 0x6680, 32},	/* PATTERN_SSO_FULL_XTALK_DQ1 */
+	{0x1f, 0xF, 2, 0xf, 0x6A80, 32},	/* PATTERN_SSO_FULL_XTALK_DQ2 */
+	{0x1f, 0xF, 2, 0xf, 0x6E80, 32},	/* PATTERN_SSO_FULL_XTALK_DQ3 */
+	{0x1f, 0xF, 2, 0xf, 0x7280, 32},	/* PATTERN_SSO_FULL_XTALK_DQ4 */
+	{0x1f, 0xF, 2, 0xf, 0x7680, 32},	/* PATTERN_SSO_FULL_XTALK_DQ5 */
+	{0x1f, 0xF, 2, 0xf, 0x7A80, 32},	/* PATTERN_SSO_FULL_XTALK_DQ6 */
+	{0x1f, 0xF, 2, 0xf, 0x7E80, 32},	/* PATTERN_SSO_FULL_XTALK_DQ7 */
+	{0x1f, 0xF, 2, 0xf, 0x8280, 32},	/* PATTERN_SSO_XTALK_FREE_DQ0 */
+	{0x1f, 0xF, 2, 0xf, 0x8680, 32},	/* PATTERN_SSO_XTALK_FREE_DQ1 */
+	{0x1f, 0xF, 2, 0xf, 0x8A80, 32},	/* PATTERN_SSO_XTALK_FREE_DQ2 */
+	{0x1f, 0xF, 2, 0xf, 0x8E80, 32},	/* PATTERN_SSO_XTALK_FREE_DQ3 */
+	{0x1f, 0xF, 2, 0xf, 0x9280, 32},	/* PATTERN_SSO_XTALK_FREE_DQ4 */
+	{0x1f, 0xF, 2, 0xf, 0x9680, 32},	/* PATTERN_SSO_XTALK_FREE_DQ5 */
+	{0x1f, 0xF, 2, 0xf, 0x9A80, 32},	/* PATTERN_SSO_XTALK_FREE_DQ6 */
+	{0x1f, 0xF, 2, 0xf, 0x9E80, 32},	/* PATTERN_SSO_XTALK_FREE_DQ7 */
+	{0x1f, 0xF, 2, 0xf, 0xA280, 32}		/* PATTERN_ISI_XTALK_FREE */
+	/* Note: actual start_address is "<< 3" of defined address */
 };
 
 u32 train_dev_num;
@@ -166,6 +323,10 @@ u32 *ddr3_tip_get_buf_ptr(u32 dev_num, enum hws_search_dir search,
 	return buf_ptr;
 }
 
+enum {
+	PASS,
+	FAIL
+};
 /*
  * IP Training search
  * Note: for one edge search only from fail to pass, else jitter can
@@ -183,18 +344,19 @@ int ddr3_tip_ip_training(u32 dev_num, enum hws_access_type access_type,
 			 enum hws_ddr_cs cs_type, u32 cs_num,
 			 enum hws_training_ip_stat *train_status)
 {
-	u32 mask_dq_num_of_regs, mask_pup_num_of_regs, index_cnt, poll_cnt,
+	u32 mask_dq_num_of_regs, mask_pup_num_of_regs, index_cnt,
 		reg_data, pup_id;
 	u32 tx_burst_size;
 	u32 delay_between_burst;
 	u32 rd_mode;
-	u32 read_data[MAX_INTERFACE_NUM];
+	u32 data;
 	struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
 	u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
 	u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
-	if (pup_num >= tm->num_of_bus_per_interface) {
+	if (pup_num >= octets_per_if_num) {
 		DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
 					 ("pup_num %d not valid\n", pup_num));
 	}
@@ -214,20 +376,20 @@ int ddr3_tip_ip_training(u32 dev_num, enum hws_access_type access_type,
 		/* All CSs to CS0     */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, access_type, interface_num,
-			      CS_ENABLE_REG, 1 << 3, 1 << 3));
+			      DUAL_DUNIT_CFG_REG, 1 << 3, 1 << 3));
 		/* All CSs to CS0     */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, access_type, interface_num,
-			      ODPG_DATA_CONTROL_REG,
+			      ODPG_DATA_CTRL_REG,
 			      (0x3 | (effective_cs << 26)), 0xc000003));
 	} else {
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, access_type, interface_num,
-			      CS_ENABLE_REG, 0, 1 << 3));
+			      DUAL_DUNIT_CFG_REG, 0, 1 << 3));
 		/*  CS select */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, access_type, interface_num,
-			      ODPG_DATA_CONTROL_REG, 0x3 | cs_num << 26,
+			      ODPG_DATA_CTRL_REG, 0x3 | cs_num << 26,
 			      0x3 | 3 << 26));
 	}
 
@@ -249,7 +411,7 @@ int ddr3_tip_ip_training(u32 dev_num, enum hws_access_type access_type,
 	reg_data |= (direction == OPER_READ) ? 0x60 : 0xfa;
 	CHECK_STATUS(ddr3_tip_if_write
 		     (dev_num, access_type, interface_num,
-		      ODPG_WRITE_READ_MODE_ENABLE_REG, reg_data,
+		      ODPG_WR_RD_MODE_ENA_REG, reg_data,
 		      MASK_ALL_BITS));
 	reg_data = (edge_comp == EDGE_PF || edge_comp == EDGE_FP) ? 0 : 1 << 6;
 	reg_data |= (edge_comp == EDGE_PF || edge_comp == EDGE_PFP) ?
@@ -272,13 +434,13 @@ int ddr3_tip_ip_training(u32 dev_num, enum hws_access_type access_type,
 
 	CHECK_STATUS(ddr3_tip_if_write
 		     (dev_num, access_type, interface_num,
-		      ODPG_TRAINING_CONTROL_REG,
+		      GENERAL_TRAINING_OPCODE_REG,
 		      reg_data | (0x7 << 8) | (0x7 << 11),
 		      (0x3 | (0x3 << 2) | (0x3 << 6) | (1 << 5) | (0x7 << 8) |
 		       (0x7 << 11) | (0xf << 14) | (0x3 << 18) | (3 << 20))));
 	reg_data = (search_dir == HWS_LOW2HIGH) ? 0 : (1 << 8);
 	CHECK_STATUS(ddr3_tip_if_write
-		     (dev_num, access_type, interface_num, ODPG_OBJ1_OPCODE_REG,
+		     (dev_num, access_type, interface_num, OPCODE_REG0_REG(1),
 		      1 | reg_data | init_value << 9 | (1 << 25) | (1 << 26),
 		      0xff | (1 << 8) | (0xffff << 9) | (1 << 25) | (1 << 26)));
 
@@ -287,7 +449,7 @@ int ddr3_tip_ip_training(u32 dev_num, enum hws_access_type access_type,
 	 * Max number of iterations
 	 */
 	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, interface_num,
-				       ODPG_OBJ1_ITER_CNT_REG, num_iter,
+				       OPCODE_REG1_REG(1), num_iter,
 				       0xffff));
 	if (control_element == HWS_CONTROL_ELEMENT_DQ_SKEW &&
 	    direction == OPER_READ) {
@@ -295,12 +457,10 @@ int ddr3_tip_ip_training(u32 dev_num, enum hws_access_type access_type,
 		 * Write2_dunit(0x10c0, 0x5f , [7:0])
 		 * MC PBS Reg Address at DDR PHY
 		 */
-		reg_data = 0x5f +
-			effective_cs * CALIBRATED_OBJECTS_REG_ADDR_OFFSET;
+		reg_data = PBS_RX_BCAST_PHY_REG(effective_cs);
 	} else if (control_element == HWS_CONTROL_ELEMENT_DQ_SKEW &&
 		   direction == OPER_WRITE) {
-		reg_data = 0x1f +
-			effective_cs * CALIBRATED_OBJECTS_REG_ADDR_OFFSET;
+		reg_data = PBS_TX_BCAST_PHY_REG(effective_cs);
 	} else if (control_element == HWS_CONTROL_ELEMENT_ADLL &&
 		   direction == OPER_WRITE) {
 		/*
@@ -311,11 +471,11 @@ int ddr3_tip_ip_training(u32 dev_num, enum hws_access_type access_type,
 		 * Write2_dunit(0x10c0, 0x1 , [7:0])
 		 * ADLL WR Reg Address at DDR PHY
 		 */
-		reg_data = 1 + effective_cs * CS_REGISTER_ADDR_OFFSET;
+		reg_data = CTX_PHY_REG(effective_cs);
 	} else if (control_element == HWS_CONTROL_ELEMENT_ADLL &&
 		   direction == OPER_READ) {
 		/* ADLL RD Reg Address@DDR PHY */
-		reg_data = 3 + effective_cs * CS_REGISTER_ADDR_OFFSET;
+		reg_data = CRX_PHY_REG(effective_cs);
 	} else if (control_element == HWS_CONTROL_ELEMENT_DQS_SKEW &&
 		   direction == OPER_WRITE) {
 		/* TBD not defined in 0.5.0 requirement  */
@@ -326,12 +486,12 @@ int ddr3_tip_ip_training(u32 dev_num, enum hws_access_type access_type,
 
 	reg_data |= (0x6 << 28);
 	CHECK_STATUS(ddr3_tip_if_write
-		     (dev_num, access_type, interface_num, CALIB_OBJ_PRFA_REG,
+		     (dev_num, access_type, interface_num, CAL_PHY_REG(1),
 		      reg_data | (init_value << 8),
 		      0xff | (0xffff << 8) | (0xf << 24) | (u32) (0xf << 28)));
 
-	mask_dq_num_of_regs = tm->num_of_bus_per_interface * BUS_WIDTH_IN_BITS;
-	mask_pup_num_of_regs = tm->num_of_bus_per_interface;
+	mask_dq_num_of_regs = octets_per_if_num * BUS_WIDTH_IN_BITS;
+	mask_pup_num_of_regs = octets_per_if_num;
 
 	if (result_type == RESULT_PER_BIT) {
 		for (index_cnt = 0; index_cnt < mask_dq_num_of_regs;
@@ -343,15 +503,12 @@ int ddr3_tip_ip_training(u32 dev_num, enum hws_access_type access_type,
 		}
 
 		/* Mask disabled buses */
-		for (pup_id = 0; pup_id < tm->num_of_bus_per_interface;
+		for (pup_id = 0; pup_id < octets_per_if_num;
 		     pup_id++) {
-			if (IS_ACTIVE(tm->bus_act_mask, pup_id) == 1)
+			if (IS_BUS_ACTIVE(tm->bus_act_mask, pup_id) == 1)
 				continue;
 
-			for (index_cnt = (mask_dq_num_of_regs - pup_id * 8);
-			     index_cnt <
-				     (mask_dq_num_of_regs - (pup_id + 1) * 8);
-			     index_cnt++) {
+			for (index_cnt = (pup_id * 8); index_cnt < (pup_id + 1) * 8; index_cnt++) {
 				CHECK_STATUS(ddr3_tip_if_write
 					     (dev_num, access_type,
 					      interface_num,
@@ -385,89 +542,24 @@ int ddr3_tip_ip_training(u32 dev_num, enum hws_access_type access_type,
 		}
 	}
 
-	/* Start Training Trigger */
-	CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, interface_num,
-				       ODPG_TRAINING_TRIGGER_REG, 1, 1));
-	/* wait for all RFU tests to finish (or timeout) */
-	/* WA for 16 bit mode, more investigation needed */
-	mdelay(1);
-
-	/* Training "Done ?" */
-	for (index_cnt = 0; index_cnt < MAX_INTERFACE_NUM; index_cnt++) {
-		if (IS_ACTIVE(tm->if_act_mask, index_cnt) == 0)
-			continue;
-
-		if (interface_mask & (1 << index_cnt)) {
-			/* need to check results for this Dunit */
-			for (poll_cnt = 0; poll_cnt < max_polling_for_done;
-			     poll_cnt++) {
-				CHECK_STATUS(ddr3_tip_if_read
-					     (dev_num, ACCESS_TYPE_UNICAST,
-					      index_cnt,
-					      ODPG_TRAINING_STATUS_REG,
-					      &reg_data, MASK_ALL_BITS));
-				if ((reg_data & 0x2) != 0) {
-					/*done */
-					train_status[index_cnt] =
-						HWS_TRAINING_IP_STATUS_SUCCESS;
-					break;
-				}
-			}
-
-			if (poll_cnt == max_polling_for_done) {
-				train_status[index_cnt] =
-					HWS_TRAINING_IP_STATUS_TIMEOUT;
-			}
-		}
-		/* Be sure that ODPG done */
-		CHECK_STATUS(is_odpg_access_done(dev_num, index_cnt));
-	}
-
-	/* Write ODPG done in Dunit */
-	CHECK_STATUS(ddr3_tip_if_write
-		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ODPG_STATUS_DONE_REG, 0, 0x1));
+	/* trigger training */
+	mv_ddr_training_enable();
 
-	/* wait for all Dunit tests to finish (or timeout) */
-	/* Training "Done ?" */
-	/* Training "Pass ?" */
-	for (index_cnt = 0; index_cnt < MAX_INTERFACE_NUM; index_cnt++) {
-		if (IS_ACTIVE(tm->if_act_mask, index_cnt) == 0)
-			continue;
-
-		if (interface_mask & (1 << index_cnt)) {
-			/* need to check results for this Dunit */
-			for (poll_cnt = 0; poll_cnt < max_polling_for_done;
-			     poll_cnt++) {
-				CHECK_STATUS(ddr3_tip_if_read
-					     (dev_num, ACCESS_TYPE_UNICAST,
-					      index_cnt,
-					      ODPG_TRAINING_TRIGGER_REG,
-					      read_data, MASK_ALL_BITS));
-				reg_data = read_data[index_cnt];
-				if ((reg_data & 0x2) != 0) {
-					/* done */
-					if ((reg_data & 0x4) == 0) {
-						train_status[index_cnt] =
-							HWS_TRAINING_IP_STATUS_SUCCESS;
-					} else {
-						train_status[index_cnt] =
-							HWS_TRAINING_IP_STATUS_FAIL;
-					}
-					break;
-				}
-			}
+	/* wa for 16-bit mode: wait for all rfu tests to finish or timeout */
+	mdelay(1);
 
-			if (poll_cnt == max_polling_for_done) {
-				train_status[index_cnt] =
-					HWS_TRAINING_IP_STATUS_TIMEOUT;
-			}
-		}
+	/* check for training done */
+	if (mv_ddr_is_training_done(MAX_POLLING_ITERATIONS, &data) != MV_OK) {
+		train_status[0] = HWS_TRAINING_IP_STATUS_TIMEOUT;
+	} else { /* training done; check for pass */
+		if (data == PASS)
+			train_status[0] = HWS_TRAINING_IP_STATUS_SUCCESS;
+		else
+			train_status[0] = HWS_TRAINING_IP_STATUS_FAIL;
 	}
 
-	CHECK_STATUS(ddr3_tip_if_write
-		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ODPG_DATA_CONTROL_REG, 0, MASK_ALL_BITS));
+	ddr3_tip_if_write(0, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+			  ODPG_DATA_CTRL_REG, 0, MASK_ALL_BITS);
 
 	return MV_OK;
 }
@@ -481,32 +573,47 @@ int ddr3_tip_load_pattern_to_odpg(u32 dev_num, enum hws_access_type access_type,
 {
 	u32 pattern_length_cnt = 0;
 	struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	for (pattern_length_cnt = 0;
 	     pattern_length_cnt < pattern_table[pattern].pattern_len;
-	     pattern_length_cnt++) {
-		CHECK_STATUS(ddr3_tip_if_write
-			     (dev_num, access_type, if_id,
-			      ODPG_PATTERN_DATA_LOW_REG,
-			      pattern_table_get_word(dev_num, pattern,
-						     (u8) (pattern_length_cnt *
-							   2)), MASK_ALL_BITS));
-		CHECK_STATUS(ddr3_tip_if_write
-			     (dev_num, access_type, if_id,
-			      ODPG_PATTERN_DATA_HI_REG,
-			      pattern_table_get_word(dev_num, pattern,
-						     (u8) (pattern_length_cnt *
-							   2 + 1)),
-			      MASK_ALL_BITS));
+	     pattern_length_cnt++) {	/* FIXME: the ecc patch below is only for a7040 A0 */
+		if (MV_DDR_IS_64BIT_DRAM_MODE(tm->bus_act_mask)/* || tm->bus_act_mask == MV_DDR_32BIT_ECC_PUP8_BUS_MASK*/) {
+			CHECK_STATUS(ddr3_tip_if_write
+				     (dev_num, access_type, if_id,
+				      ODPG_DATA_WR_DATA_LOW_REG,
+				      pattern_table_get_word(dev_num, pattern,
+							     (u8) (pattern_length_cnt)),
+				      MASK_ALL_BITS));
+			CHECK_STATUS(ddr3_tip_if_write
+				     (dev_num, access_type, if_id,
+				      ODPG_DATA_WR_DATA_HIGH_REG,
+				      pattern_table_get_word(dev_num, pattern,
+							     (u8) (pattern_length_cnt)),
+				      MASK_ALL_BITS));
+		} else {
+			CHECK_STATUS(ddr3_tip_if_write
+				     (dev_num, access_type, if_id,
+					      ODPG_DATA_WR_DATA_LOW_REG,
+				      pattern_table_get_word(dev_num, pattern,
+							     (u8) (pattern_length_cnt * 2)),
+				      MASK_ALL_BITS));
+			CHECK_STATUS(ddr3_tip_if_write
+				     (dev_num, access_type, if_id,
+				      ODPG_DATA_WR_DATA_HIGH_REG,
+				      pattern_table_get_word(dev_num, pattern,
+							     (u8) (pattern_length_cnt * 2 + 1)),
+				      MASK_ALL_BITS));
+		}
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, access_type, if_id,
-			      ODPG_PATTERN_ADDR_REG, pattern_length_cnt,
+			      ODPG_DATA_WR_ADDR_REG, pattern_length_cnt,
 			      MASK_ALL_BITS));
 	}
 
 	CHECK_STATUS(ddr3_tip_if_write
 		     (dev_num, access_type, if_id,
-		      ODPG_PATTERN_ADDR_OFFSET_REG, load_addr, MASK_ALL_BITS));
+		      ODPG_DATA_BUFFER_OFFS_REG, load_addr, MASK_ALL_BITS));
 
 	return MV_OK;
 }
@@ -528,7 +635,7 @@ int ddr3_tip_configure_odpg(u32 dev_num, enum hws_access_type access_type,
 		      (rx_phases << 21) | (rd_mode << 25) | (cs_num << 26) |
 		      (addr_stress_jump << 29));
 	ret = ddr3_tip_if_write(dev_num, access_type, if_id,
-				ODPG_DATA_CONTROL_REG, data_value, 0xaffffffc);
+				ODPG_DATA_CTRL_REG, data_value, 0xaffffffc);
 	if (ret != MV_OK)
 		return ret;
 
@@ -598,7 +705,8 @@ int ddr3_tip_read_training_result(u32 dev_num, u32 if_id,
 	u32 read_data[MAX_INTERFACE_NUM];
 	u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
 	u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	/*
 	 * Agreed assumption: all CS mask contain same number of bits,
@@ -606,11 +714,11 @@ int ddr3_tip_read_training_result(u32 dev_num, u32 if_id,
 	 * all pups
 	 */
 	CHECK_STATUS(ddr3_tip_if_write
-		     (dev_num, ACCESS_TYPE_UNICAST, if_id, CS_ENABLE_REG,
+		     (dev_num, ACCESS_TYPE_UNICAST, if_id, DUAL_DUNIT_CFG_REG,
 		      (cs_num_type == 0) ? 1 << 3 : 0, (1 << 3)));
 	CHECK_STATUS(ddr3_tip_if_write
 		     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-		      ODPG_DATA_CONTROL_REG, (cs_num_type << 26), (3 << 26)));
+		      ODPG_DATA_CTRL_REG, (cs_num_type << 26), (3 << 26)));
 	DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_TRACE,
 				 ("Read_from_d_b %d cs_type %d oper %d result_type %d direction %d search %d pup_num %d if_id %d pup_access_type %d\n",
 				  is_read_from_db, cs_num_type, operation,
@@ -622,7 +730,7 @@ int ddr3_tip_read_training_result(u32 dev_num, u32 if_id,
 					 ("ddr3_tip_read_training_result load_res = NULL"));
 		return MV_FAIL;
 	}
-	if (pup_num >= tm->num_of_bus_per_interface) {
+	if (pup_num >= octets_per_if_num) {
 		DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
 					 ("pup_num %d not valid\n", pup_num));
 	}
@@ -640,11 +748,11 @@ int ddr3_tip_read_training_result(u32 dev_num, u32 if_id,
 	} else {		/*pup_access_type == ACCESS_TYPE_MULTICAST) */
 
 		start_pup = 0;
-		end_pup = tm->num_of_bus_per_interface - 1;
+		end_pup = octets_per_if_num - 1;
 	}
 
 	for (pup_cnt = start_pup; pup_cnt <= end_pup; pup_cnt++) {
-		VALIDATE_ACTIVE(tm->bus_act_mask, pup_cnt);
+		VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup_cnt);
 		DEBUG_TRAINING_IP_ENGINE(
 			DEBUG_LEVEL_TRACE,
 			("if_id %d start_pup %d end_pup %d pup_cnt %d\n",
@@ -690,11 +798,11 @@ int ddr3_tip_read_training_result(u32 dev_num, u32 if_id,
 						      MASK_ALL_BITS));
 					if (is_check_result_validity == 1) {
 						if ((read_data[if_id] &
-						     0x02000000) == 0) {
+						     TIP_ENG_LOCK) == 0) {
 							interface_train_res
 								[reg_offset] =
-								0x02000000 +
-								64 + cons_tap;
+								TIP_ENG_LOCK +
+								TIP_TX_DLL_RANGE_MAX;
 						} else {
 							interface_train_res
 								[reg_offset] =
@@ -738,60 +846,27 @@ int ddr3_tip_read_training_result(u32 dev_num, u32 if_id,
 int ddr3_tip_load_all_pattern_to_mem(u32 dev_num)
 {
 	u32 pattern = 0, if_id;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		training_result[training_stage][if_id] = TEST_SUCCESS;
 	}
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		/* enable single cs */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      CS_ENABLE_REG, (1 << 3), (1 << 3)));
+			      DUAL_DUNIT_CFG_REG, (1 << 3), (1 << 3)));
 	}
 
-	for (pattern = 0; pattern < PATTERN_LIMIT; pattern++)
+	for (pattern = 0; pattern < PATTERN_LAST; pattern++)
 		ddr3_tip_load_pattern_to_mem(dev_num, pattern);
 
 	return MV_OK;
 }
 
-/*
- * Wait till ODPG access is ready
- */
-int is_odpg_access_done(u32 dev_num, u32 if_id)
-{
-	u32 poll_cnt = 0, data_value;
-	u32 read_data[MAX_INTERFACE_NUM];
-
-	for (poll_cnt = 0; poll_cnt < MAX_POLLING_ITERATIONS; poll_cnt++) {
-		CHECK_STATUS(ddr3_tip_if_read
-			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      ODPG_BIST_DONE, read_data, MASK_ALL_BITS));
-		data_value = read_data[if_id];
-		if (((data_value >> ODPG_BIST_DONE_BIT_OFFS) & 0x1) ==
-		    ODPG_BIST_DONE_BIT_VALUE) {
-				data_value = data_value & 0xfffffffe;
-				CHECK_STATUS(ddr3_tip_if_write
-					     (dev_num, ACCESS_TYPE_UNICAST,
-					      if_id, ODPG_BIST_DONE, data_value,
-					      MASK_ALL_BITS));
-				break;
-			}
-	}
-
-	if (poll_cnt >= MAX_POLLING_ITERATIONS) {
-		DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
-					 ("Bist Activate: poll failure 2\n"));
-		return MV_FAIL;
-	}
-
-	return MV_OK;
-}
-
 /*
  * Load specific pattern to memory using ODPG
  */
@@ -799,7 +874,7 @@ int ddr3_tip_load_pattern_to_mem(u32 dev_num, enum hws_pattern pattern)
 {
 	u32 reg_data, if_id;
 	struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	/* load pattern to memory */
 	/*
@@ -814,73 +889,65 @@ int ddr3_tip_load_pattern_to_mem(u32 dev_num, enum hws_pattern pattern)
 		(effective_cs << 26);
 	CHECK_STATUS(ddr3_tip_if_write
 		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ODPG_DATA_CONTROL_REG, reg_data, MASK_ALL_BITS));
+		      ODPG_DATA_CTRL_REG, reg_data, MASK_ALL_BITS));
 	/* ODPG Write enable from BIST */
 	CHECK_STATUS(ddr3_tip_if_write
 		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ODPG_DATA_CONTROL_REG, (0x1 | (effective_cs << 26)),
+		      ODPG_DATA_CTRL_REG, (0x1 | (effective_cs << 26)),
 		      0xc000003));
 	/* disable error injection */
 	CHECK_STATUS(ddr3_tip_if_write
 		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ODPG_WRITE_DATA_ERROR_REG, 0, 0x1));
+		      ODPG_DATA_WR_DATA_ERR_REG, 0, 0x1));
 	/* load pattern to ODPG */
 	ddr3_tip_load_pattern_to_odpg(dev_num, ACCESS_TYPE_MULTICAST,
 				      PARAM_NOT_CARE, pattern,
 				      pattern_table[pattern].start_addr);
 
-	for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
-		if (IS_ACTIVE(tm->if_act_mask, if_id) == 0)
-			continue;
+	if (ddr3_tip_dev_attr_get(dev_num, MV_ATTR_TIP_REV) >= MV_TIP_REV_3) {
+		for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 
+			CHECK_STATUS(ddr3_tip_if_write
+				     (dev_num, ACCESS_TYPE_UNICAST, if_id,
+				      SDRAM_ODT_CTRL_HIGH_REG,
+				      0x3, 0xf));
+		}
+
+		mv_ddr_odpg_enable();
+	} else {
 		CHECK_STATUS(ddr3_tip_if_write
-			     (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x1498,
-			      0x3, 0xf));
+			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+			      ODPG_DATA_CTRL_REG, (u32)(0x1 << 31),
+			      (u32)(0x1 << 31)));
 	}
-
-	CHECK_STATUS(ddr3_tip_if_write
-		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ODPG_ENABLE_REG, 0x1 << ODPG_ENABLE_OFFS,
-		      (0x1 << ODPG_ENABLE_OFFS)));
-
 	mdelay(1);
 
-	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-		CHECK_STATUS(is_odpg_access_done(dev_num, if_id));
-	}
+	if (mv_ddr_is_odpg_done(MAX_POLLING_ITERATIONS) != MV_OK)
+		return MV_FAIL;
 
 	/* Disable ODPG and stop write to memory */
 	CHECK_STATUS(ddr3_tip_if_write
 		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ODPG_DATA_CONTROL_REG, (0x1 << 30), (u32) (0x3 << 30)));
+		      ODPG_DATA_CTRL_REG, (0x1 << 30), (u32) (0x3 << 30)));
 
 	/* return to default */
 	CHECK_STATUS(ddr3_tip_if_write
 		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ODPG_DATA_CONTROL_REG, 0, MASK_ALL_BITS));
-
-	/* Disable odt0 for CS0 training - need to adjust for multy CS */
-	CHECK_STATUS(ddr3_tip_if_write
-		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x1498,
-		      0x0, 0xf));
+		      ODPG_DATA_CTRL_REG, 0, MASK_ALL_BITS));
 
+	if (ddr3_tip_dev_attr_get(dev_num, MV_ATTR_TIP_REV) >= MV_TIP_REV_3) {
+		/* Disable odt0 for CS0 training - need to adjust for multy CS */
+		CHECK_STATUS(ddr3_tip_if_write
+			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+			      SDRAM_ODT_CTRL_HIGH_REG, 0x0, 0xf));
+	}
 	/* temporary added */
 	mdelay(1);
 
 	return MV_OK;
 }
 
-/*
- * Load specific pattern to memory using CPU
- */
-int ddr3_tip_load_pattern_to_mem_by_cpu(u32 dev_num, enum hws_pattern pattern,
-					u32 offset)
-{
-	/* eranba - TBD */
-	return MV_OK;
-}
-
 /*
  * Training search routine
  */
@@ -903,8 +970,9 @@ int ddr3_tip_ip_training_wrapper_int(u32 dev_num,
 	u32 interface_num = 0, start_if, end_if, init_value_used;
 	enum hws_search_dir search_dir_id, start_search, end_search;
 	enum hws_edge_compare edge_comp_used;
-	u8 cons_tap = (direction == OPER_WRITE) ? (64) : (0);
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u8 cons_tap = 0;
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	if (train_status == NULL) {
 		DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
@@ -914,12 +982,12 @@ int ddr3_tip_ip_training_wrapper_int(u32 dev_num,
 
 	if ((train_cs_type > CS_NON_SINGLE) ||
 	    (edge_comp >= EDGE_PFP) ||
-	    (pattern >= PATTERN_LIMIT) ||
+	    (pattern >= PATTERN_LAST) ||
 	    (direction > OPER_WRITE_AND_READ) ||
 	    (search_dir > HWS_HIGH2LOW) ||
 	    (control_element > HWS_CONTROL_ELEMENT_DQS_SKEW) ||
 	    (result_type > RESULT_PER_BYTE) ||
-	    (pup_num >= tm->num_of_bus_per_interface) ||
+	    (pup_num >= octets_per_if_num) ||
 	    (pup_access_type > ACCESS_TYPE_MULTICAST) ||
 	    (if_id > 11) || (access_type > ACCESS_TYPE_MULTICAST)) {
 		DEBUG_TRAINING_IP_ENGINE(
@@ -969,7 +1037,7 @@ int ddr3_tip_ip_training_wrapper_int(u32 dev_num,
 
 		for (interface_num = start_if; interface_num <= end_if;
 		     interface_num++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, interface_num);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, interface_num);
 			cs_num = 0;
 			CHECK_STATUS(ddr3_tip_read_training_result
 				     (dev_num, interface_num, pup_access_type,
@@ -983,48 +1051,99 @@ int ddr3_tip_ip_training_wrapper_int(u32 dev_num,
 
 	return MV_OK;
 }
-
 /*
  * Training search & read result routine
+ * This function implements the search algorithm
+ * first it calls the function ddr3_tip_ip_training_wrapper_int which triggers the search from l2h and h2l
+ * this function handles rx and tx search cases
+ * in case of rx it only triggers the search (l2h and h2l)
+ * in case of tx there are 3 optional algorithm phases:
+ * phase 1:
+ * it first triggers the search and handles the results as following (phase 1):
+ * each bit, which defined by the search two edges (e1 or VW_L and e2 or VW_H), match on of cases:
+ *  1.	BIT_LOW_UI	0 =< VW =< 31 in case of jitter use: VW_L <= 31, VW_H <= 31
+ *  2.	BIT_HIGH_UI	32 =< VW =< 63 in case of jitter use: VW_L >= 32, VW_H >= 32
+ *  3.	BIT_SPLIT_IN	VW_L <= 31 & VW_H >= 32
+ *  4.	BIT_SPLIT_OUT*	VW_H < 32 &  VW_L > 32
+ * note: the VW units is adll taps
+ * phase 2:
+ * only bit case BIT_SPLIT_OUT requires another search (phase 2) from the middle range in two directions h2l and l2h
+ * because only this case is not locked by the search engine in the first search trigger (phase 1).
+ * phase 3:
+ * each subphy is categorized according to its bits definition.
+ * the sub-phy cases are as follows:
+ *  1.BYTE_NOT_DEFINED			the byte has not yet been categorized
+ *  2.BYTE_HOMOGENEOUS_LOW		0 =< VW =< 31
+ *  3.BYTE_HOMOGENEOUS_HIGH		32 =< VW =< 63
+ *  4.BYTE_HOMOGENEOUS_SPLIT_IN		VW_L <= 31 & VW_H >= 32
+ *					or the center of all bits in the byte  =< 31
+ *  5.BYTE_HOMOGENEOUS_SPLIT_OUT	VW_H < 32 &  VW_L > 32
+ *  6.BYTE_SPLIT_OUT_MIX		at least one bits is in split out state and one bit is in other
+ *					or the center of all bits in the byte => 32
+ * after the two phases above a center valid window for each subphy is calculated accordingly:
+ * center valid window = maximum center of all bits in the subphy - minimum center of all bits in the subphy.
+ * now decisions are made in each subphy as following:
+ * all subphys which are homogeneous remains as is
+ * all subphys which are homogeneous low | homogeneous high and the subphy center valid window is less than 32
+ *	mark this subphy as homogeneous split in.
+ * now the bits in the bytes which are BYTE_SPLIT_OUT_MIX needed to be reorganized and handles as following
+ * all bits which are BIT_LOW_UI will be added with 64 adll,
+ * this will hopefully ensures that all the bits in the sub phy can be sampled by the dqs
  */
 int ddr3_tip_ip_training_wrapper(u32 dev_num, enum hws_access_type access_type,
-				 u32 if_id,
-				 enum hws_access_type pup_access_type,
-				 u32 pup_num,
-				 enum hws_training_result result_type,
-				 enum hws_control_element control_element,
-				 enum hws_search_dir search_dir,
-				 enum hws_dir direction, u32 interface_mask,
-				 u32 init_value_l2h, u32 init_value_h2l,
-				 u32 num_iter, enum hws_pattern pattern,
-				 enum hws_edge_compare edge_comp,
-				 enum hws_ddr_cs train_cs_type, u32 cs_num,
-				 enum hws_training_ip_stat *train_status)
+	u32 if_id,
+	enum hws_access_type pup_access_type,
+	u32 pup_num,
+	enum hws_training_result result_type,
+	enum hws_control_element control_element,
+	enum hws_search_dir search_dir,
+	enum hws_dir direction, u32 interface_mask,
+	u32 init_value_l2h, u32 init_value_h2l,
+	u32 num_iter, enum hws_pattern pattern,
+	enum hws_edge_compare edge_comp,
+	enum hws_ddr_cs train_cs_type, u32 cs_num,
+	enum hws_training_ip_stat *train_status)
 {
 	u8 e1, e2;
-	u32 interface_cnt, bit_id, start_if, end_if, bit_end = 0;
+	u32 bit_id, start_if, end_if, bit_end = 0;
 	u32 *result[HWS_SEARCH_DIR_LIMIT] = { 0 };
 	u8 cons_tap = (direction == OPER_WRITE) ? (64) : (0);
 	u8 bit_bit_mask[MAX_BUS_NUM] = { 0 }, bit_bit_mask_active = 0;
-	u8 pup_id;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
-
-	if (pup_num >= tm->num_of_bus_per_interface) {
+	u8 bit_state[MAX_BUS_NUM * BUS_WIDTH_IN_BITS] = {0};
+	u8 h2l_adll_value[MAX_BUS_NUM][BUS_WIDTH_IN_BITS];
+	u8 l2h_adll_value[MAX_BUS_NUM][BUS_WIDTH_IN_BITS];
+	u8 center_subphy_adll_window[MAX_BUS_NUM];
+	u8 min_center_subphy_adll[MAX_BUS_NUM];
+	u8 max_center_subphy_adll[MAX_BUS_NUM];
+	u32 *l2h_if_train_res = NULL;
+	u32 *h2l_if_train_res = NULL;
+	enum hws_search_dir search_dir_id;
+	int status;
+	u32 bit_lock_result;
+
+	u8 sybphy_id;
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+
+	if (pup_num >= octets_per_if_num) {
 		DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
-					 ("pup_num %d not valid\n", pup_num));
+			("pup_num %d not valid\n", pup_num));
 	}
 
 	if (if_id >= MAX_INTERFACE_NUM) {
 		DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
-					 ("if_id %d not valid\n", if_id));
+			("if_id %d not valid\n", if_id));
 	}
 
-	CHECK_STATUS(ddr3_tip_ip_training_wrapper_int
-		     (dev_num, access_type, if_id, pup_access_type, pup_num,
-		      ALL_BITS_PER_PUP, result_type, control_element,
-		      search_dir, direction, interface_mask, init_value_l2h,
-		      init_value_h2l, num_iter, pattern, edge_comp,
-		      train_cs_type, cs_num, train_status));
+	status = ddr3_tip_ip_training_wrapper_int
+		(dev_num, access_type, if_id, pup_access_type, pup_num,
+		ALL_BITS_PER_PUP, result_type, control_element,
+		search_dir, direction, interface_mask, init_value_l2h,
+		init_value_h2l, num_iter, pattern, edge_comp,
+		train_cs_type, cs_num, train_status);
+
+	if (MV_OK != status)
+		return status;
 
 	if (access_type == ACCESS_TYPE_MULTICAST) {
 		start_if = 0;
@@ -1034,181 +1153,337 @@ int ddr3_tip_ip_training_wrapper(u32 dev_num, enum hws_access_type access_type,
 		end_if = if_id;
 	}
 
-	for (interface_cnt = start_if; interface_cnt <= end_if;
-	     interface_cnt++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, interface_cnt);
-		for (pup_id = 0;
-		     pup_id <= (tm->num_of_bus_per_interface - 1); pup_id++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, pup_id);
+	for (if_id = start_if; if_id <= end_if; if_id++) {
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+		/* zero the database */
+		bit_bit_mask_active = 0;	/* clean the flag for level2 search */
+		memset(bit_state, 0, sizeof(bit_state));
+		/* phase 1 */
+		for (sybphy_id = 0; sybphy_id < octets_per_if_num; sybphy_id++) {
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, sybphy_id);
 			if (result_type == RESULT_PER_BIT)
-				bit_end = BUS_WIDTH_IN_BITS - 1;
+				bit_end = BUS_WIDTH_IN_BITS;
 			else
 				bit_end = 0;
 
-			bit_bit_mask[pup_id] = 0;
-			for (bit_id = 0; bit_id <= bit_end; bit_id++) {
-				enum hws_search_dir search_dir_id;
-				for (search_dir_id = HWS_LOW2HIGH;
-				     search_dir_id <= HWS_HIGH2LOW;
-				     search_dir_id++) {
-					CHECK_STATUS
-						(ddr3_tip_read_training_result
-						 (dev_num, interface_cnt,
-						  ACCESS_TYPE_UNICAST, pup_id,
-						  bit_id, search_dir_id,
-						  direction, result_type,
-						  TRAINING_LOAD_OPERATION_UNLOAD,
-						  CS_SINGLE,
-						  &result[search_dir_id],
-						  1, 0, 0));
+			/* zero the data base */
+			bit_bit_mask[sybphy_id] = 0;
+			byte_status[if_id][sybphy_id] = BYTE_NOT_DEFINED;
+			for (bit_id = 0; bit_id < bit_end; bit_id++) {
+				h2l_adll_value[sybphy_id][bit_id] = 64;
+				l2h_adll_value[sybphy_id][bit_id] = 0;
+				for (search_dir_id = HWS_LOW2HIGH; search_dir_id <= HWS_HIGH2LOW;
+					search_dir_id++) {
+					status = ddr3_tip_read_training_result
+						(dev_num, if_id,
+							ACCESS_TYPE_UNICAST, sybphy_id, bit_id,
+							search_dir_id, direction, result_type,
+							TRAINING_LOAD_OPERATION_UNLOAD, CS_SINGLE,
+							&result[search_dir_id], 1, 0, 0);
+
+					if (MV_OK != status)
+						return status;
 				}
-				e1 = GET_TAP_RESULT(result[HWS_LOW2HIGH][0],
-						    EDGE_1);
-				e2 = GET_TAP_RESULT(result[HWS_HIGH2LOW][0],
-						    EDGE_1);
-				DEBUG_TRAINING_IP_ENGINE(
-					DEBUG_LEVEL_INFO,
-					("wrapper if_id %d pup_id %d bit %d l2h 0x%x (e1 0x%x) h2l 0x%x (e2 0x%x)\n",
-					 interface_cnt, pup_id, bit_id,
-					 result[HWS_LOW2HIGH][0], e1,
+
+				e1 = GET_TAP_RESULT(result[HWS_LOW2HIGH][0], EDGE_1);
+				e2 = GET_TAP_RESULT(result[HWS_HIGH2LOW][0], EDGE_1);
+				DEBUG_TRAINING_IP_ENGINE
+					(DEBUG_LEVEL_INFO,
+					 ("if_id %d sybphy_id %d bit %d l2h 0x%x (e1 0x%x) h2l 0x%x (e2 0x%x)\n",
+					 if_id, sybphy_id, bit_id, result[HWS_LOW2HIGH][0], e1,
 					 result[HWS_HIGH2LOW][0], e2));
-				/* TBD validate is valid only for tx */
-				if (VALIDATE_TRAINING_LIMIT(e1, e2) == 1 &&
-				    GET_LOCK_RESULT(result[HWS_LOW2HIGH][0]) &&
-				    GET_LOCK_RESULT(result[HWS_LOW2HIGH][0])) {
-					/* Mark problem bits */
-					bit_bit_mask[pup_id] |= 1 << bit_id;
-					bit_bit_mask_active = 1;
+				bit_lock_result =
+					(GET_LOCK_RESULT(result[HWS_LOW2HIGH][0]) &&
+						GET_LOCK_RESULT(result[HWS_HIGH2LOW][0]));
+
+				if (bit_lock_result) {
+					/* in case of read operation set the byte status as homogeneous low */
+					if (direction == OPER_READ) {
+						byte_status[if_id][sybphy_id] |= BYTE_HOMOGENEOUS_LOW;
+					} else if ((e2 - e1) > 32) { /* oper_write */
+						/* split out */
+						bit_state[sybphy_id * BUS_WIDTH_IN_BITS + bit_id] =
+							BIT_SPLIT_OUT;
+						byte_status[if_id][sybphy_id] |= BYTE_HOMOGENEOUS_SPLIT_OUT;
+						/* mark problem bits */
+						bit_bit_mask[sybphy_id] |= (1 << bit_id);
+						bit_bit_mask_active = 1;
+						DEBUG_TRAINING_IP_ENGINE
+							(DEBUG_LEVEL_TRACE,
+							 ("if_id %d sybphy_id %d bit %d BIT_SPLIT_OUT\n",
+							 if_id, sybphy_id, bit_id));
+					} else {
+						/* low ui */
+						if (e1 <= 31 && e2 <= 31) {
+							bit_state[sybphy_id * BUS_WIDTH_IN_BITS + bit_id] =
+								BIT_LOW_UI;
+							byte_status[if_id][sybphy_id] |= BYTE_HOMOGENEOUS_LOW;
+							l2h_adll_value[sybphy_id][bit_id] = e1;
+							h2l_adll_value[sybphy_id][bit_id] = e2;
+							DEBUG_TRAINING_IP_ENGINE
+								(DEBUG_LEVEL_TRACE,
+								 ("if_id %d sybphy_id %d bit %d BIT_LOW_UI\n",
+								 if_id, sybphy_id, bit_id));
+						}
+							/* high ui */
+						if (e1 >= 32 && e2 >= 32) {
+							bit_state[sybphy_id * BUS_WIDTH_IN_BITS + bit_id] =
+								BIT_HIGH_UI;
+							byte_status[if_id][sybphy_id] |= BYTE_HOMOGENEOUS_HIGH;
+							l2h_adll_value[sybphy_id][bit_id] = e1;
+							h2l_adll_value[sybphy_id][bit_id] = e2;
+							DEBUG_TRAINING_IP_ENGINE
+								(DEBUG_LEVEL_TRACE,
+								 ("if_id %d sybphy_id %d bit %d BIT_HIGH_UI\n",
+								 if_id, sybphy_id, bit_id));
+						}
+						/* split in */
+						if (e1 <= 31 && e2 >= 32) {
+							bit_state[sybphy_id * BUS_WIDTH_IN_BITS + bit_id] =
+								BIT_SPLIT_IN;
+							byte_status[if_id][sybphy_id] |=
+								BYTE_HOMOGENEOUS_SPLIT_IN;
+							l2h_adll_value[sybphy_id][bit_id] = e1;
+							h2l_adll_value[sybphy_id][bit_id] = e2;
+							DEBUG_TRAINING_IP_ENGINE
+								(DEBUG_LEVEL_TRACE,
+								 ("if_id %d sybphy_id %d bit %d BIT_SPLIT_IN\n",
+								 if_id, sybphy_id, bit_id));
+						}
+					}
+				} else {
+					DEBUG_TRAINING_IP_ENGINE
+						(DEBUG_LEVEL_INFO,
+						 ("if_id %d sybphy_id %d bit %d l2h 0x%x (e1 0x%x)"
+						 "h2l 0x%x (e2 0x%x): bit cannot be categorized\n",
+						 if_id, sybphy_id, bit_id, result[HWS_LOW2HIGH][0], e1,
+						 result[HWS_HIGH2LOW][0], e2));
+					/* mark the byte as not defined */
+					byte_status[if_id][sybphy_id] = BYTE_NOT_DEFINED;
+					break; /* continue to next pup - no reason to analyze this byte */
 				}
-			}	/* For all bits */
-		}		/* For all PUPs */
+			} /* for all bits */
+		} /* for all PUPs */
 
-		/* Fix problem bits */
+		/* phase 2 will occur only in write operation */
 		if (bit_bit_mask_active != 0) {
-			u32 *l2h_if_train_res = NULL;
-			u32 *h2l_if_train_res = NULL;
-			l2h_if_train_res =
-				ddr3_tip_get_buf_ptr(dev_num, HWS_LOW2HIGH,
-						     result_type,
-						     interface_cnt);
-			h2l_if_train_res =
-				ddr3_tip_get_buf_ptr(dev_num, HWS_HIGH2LOW,
-						     result_type,
-						     interface_cnt);
-
-			ddr3_tip_ip_training(dev_num, ACCESS_TYPE_UNICAST,
-					     interface_cnt,
-					     ACCESS_TYPE_MULTICAST,
-					     PARAM_NOT_CARE, result_type,
-					     control_element, HWS_LOW2HIGH,
-					     direction, interface_mask,
-					     num_iter / 2, num_iter / 2,
-					     pattern, EDGE_FP, train_cs_type,
-					     cs_num, train_status);
-
-			for (pup_id = 0;
-			     pup_id <= (tm->num_of_bus_per_interface - 1);
-			     pup_id++) {
-				VALIDATE_ACTIVE(tm->bus_act_mask, pup_id);
-
-				if (bit_bit_mask[pup_id] == 0)
-					continue;
-
-				for (bit_id = 0; bit_id <= bit_end; bit_id++) {
-					if ((bit_bit_mask[pup_id] &
-					     (1 << bit_id)) == 0)
+			l2h_if_train_res = ddr3_tip_get_buf_ptr(dev_num, HWS_LOW2HIGH, result_type, if_id);
+			h2l_if_train_res = ddr3_tip_get_buf_ptr(dev_num, HWS_HIGH2LOW, result_type, if_id);
+			/* search from middle to end */
+			ddr3_tip_ip_training
+				(dev_num, ACCESS_TYPE_UNICAST,
+				 if_id, ACCESS_TYPE_MULTICAST,
+				 PARAM_NOT_CARE, result_type,
+				 control_element, HWS_LOW2HIGH,
+				 direction, interface_mask,
+				 num_iter / 2, num_iter / 2,
+				 pattern, EDGE_FP, train_cs_type,
+				 cs_num, train_status);
+
+			for (sybphy_id = 0; sybphy_id < octets_per_if_num; sybphy_id++) {
+				VALIDATE_BUS_ACTIVE(tm->bus_act_mask, sybphy_id);
+				if (byte_status[if_id][sybphy_id] != BYTE_NOT_DEFINED) {
+					if (bit_bit_mask[sybphy_id] == 0)
+						continue; /* this byte bits have no split out state */
+
+					for (bit_id = 0; bit_id < bit_end; bit_id++) {
+						if ((bit_bit_mask[sybphy_id] & (1 << bit_id)) == 0)
+							continue; /* this bit is non split goto next bit */
+
+						/* enter the result to the data base */
+						status = ddr3_tip_read_training_result
+							(dev_num, if_id, ACCESS_TYPE_UNICAST, sybphy_id,
+							 bit_id, HWS_LOW2HIGH, direction, result_type,
+							 TRAINING_LOAD_OPERATION_UNLOAD, CS_SINGLE,
+							 &l2h_if_train_res, 0, 0, 1);
+
+						if (MV_OK != status)
+							return status;
+
+						l2h_adll_value[sybphy_id][bit_id] =
+							l2h_if_train_res[sybphy_id *
+							BUS_WIDTH_IN_BITS + bit_id] & PUP_RESULT_EDGE_1_MASK;
+					}
+				}
+			}
+			/* Search from middle to start */
+			ddr3_tip_ip_training
+				(dev_num, ACCESS_TYPE_UNICAST,
+				 if_id, ACCESS_TYPE_MULTICAST,
+				 PARAM_NOT_CARE, result_type,
+				 control_element, HWS_HIGH2LOW,
+				 direction, interface_mask,
+				 num_iter / 2, num_iter / 2,
+				 pattern, EDGE_FP, train_cs_type,
+				 cs_num, train_status);
+
+			for (sybphy_id = 0; sybphy_id < octets_per_if_num; sybphy_id++) {
+				VALIDATE_BUS_ACTIVE(tm->bus_act_mask, sybphy_id);
+				if (byte_status[if_id][sybphy_id] != BYTE_NOT_DEFINED) {
+					if (bit_bit_mask[sybphy_id] == 0)
 						continue;
-					CHECK_STATUS
-						(ddr3_tip_read_training_result
-						 (dev_num, interface_cnt,
-						  ACCESS_TYPE_UNICAST, pup_id,
-						  bit_id, HWS_LOW2HIGH,
-						  direction,
-						  result_type,
-						  TRAINING_LOAD_OPERATION_UNLOAD,
-						  CS_SINGLE, &l2h_if_train_res,
-						  0, 0, 1));
+
+					for (bit_id = 0; bit_id < bit_end; bit_id++) {
+						if ((bit_bit_mask[sybphy_id] & (1 << bit_id)) == 0)
+							continue;
+
+						status = ddr3_tip_read_training_result
+							(dev_num, if_id, ACCESS_TYPE_UNICAST, sybphy_id,
+							 bit_id, HWS_HIGH2LOW, direction, result_type,
+							 TRAINING_LOAD_OPERATION_UNLOAD, CS_SINGLE,
+							 &h2l_if_train_res, 0, cons_tap, 1);
+
+						if (MV_OK != status)
+							return status;
+
+						h2l_adll_value[sybphy_id][bit_id] =
+							h2l_if_train_res[sybphy_id *
+							BUS_WIDTH_IN_BITS + bit_id] & PUP_RESULT_EDGE_1_MASK;
+					}
 				}
 			}
+		} /* end if bit_bit_mask_active */
+		/*
+			* phase 3 will occur only in write operation
+			* find the maximum and the minimum center of each subphy
+			*/
+		for (sybphy_id = 0; sybphy_id < octets_per_if_num; sybphy_id++) {
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, sybphy_id);
+
+			if ((byte_status[if_id][sybphy_id] != BYTE_NOT_DEFINED) && (direction == OPER_WRITE)) {
+				/* clear the arrays and parameters */
+				center_subphy_adll_window[sybphy_id] = 0;
+				max_center_subphy_adll[sybphy_id] = 0;
+				min_center_subphy_adll[sybphy_id] = 64;
+				/* find the max and min center adll value in the current subphy */
+				for (bit_id = 0; bit_id < bit_end; bit_id++) {
+					/* debug print all the bit edges after alignment */
+					DEBUG_TRAINING_IP_ENGINE
+						(DEBUG_LEVEL_TRACE,
+						 ("if_id %d sybphy_id %d bit %d l2h %d h2l %d\n",
+						 if_id, sybphy_id, bit_id, l2h_adll_value[sybphy_id][bit_id],
+						 h2l_adll_value[sybphy_id][bit_id]));
+
+					if (((l2h_adll_value[sybphy_id][bit_id] +
+					      h2l_adll_value[sybphy_id][bit_id]) / 2) >
+					      max_center_subphy_adll[sybphy_id])
+						max_center_subphy_adll[sybphy_id] =
+						(l2h_adll_value[sybphy_id][bit_id] +
+						 h2l_adll_value[sybphy_id][bit_id]) / 2;
+					if (((l2h_adll_value[sybphy_id][bit_id] +
+					      h2l_adll_value[sybphy_id][bit_id]) / 2) <
+					      min_center_subphy_adll[sybphy_id])
+						min_center_subphy_adll[sybphy_id] =
+						(l2h_adll_value[sybphy_id][bit_id] +
+						 h2l_adll_value[sybphy_id][bit_id]) / 2;
+				}
 
-			ddr3_tip_ip_training(dev_num, ACCESS_TYPE_UNICAST,
-					     interface_cnt,
-					     ACCESS_TYPE_MULTICAST,
-					     PARAM_NOT_CARE, result_type,
-					     control_element, HWS_HIGH2LOW,
-					     direction, interface_mask,
-					     num_iter / 2, num_iter / 2,
-					     pattern, EDGE_FP, train_cs_type,
-					     cs_num, train_status);
-
-			for (pup_id = 0;
-			     pup_id <= (tm->num_of_bus_per_interface - 1);
-			     pup_id++) {
-				VALIDATE_ACTIVE(tm->bus_act_mask, pup_id);
-
-				if (bit_bit_mask[pup_id] == 0)
-					continue;
-
-				for (bit_id = 0; bit_id <= bit_end; bit_id++) {
-					if ((bit_bit_mask[pup_id] &
-					     (1 << bit_id)) == 0)
-						continue;
-					CHECK_STATUS
-						(ddr3_tip_read_training_result
-						 (dev_num, interface_cnt,
-						  ACCESS_TYPE_UNICAST, pup_id,
-						  bit_id, HWS_HIGH2LOW, direction,
-						  result_type,
-						  TRAINING_LOAD_OPERATION_UNLOAD,
-						  CS_SINGLE, &h2l_if_train_res,
-						  0, cons_tap, 1));
+				/* calculate the center of the current subphy */
+				center_subphy_adll_window[sybphy_id] =
+					max_center_subphy_adll[sybphy_id] -
+					min_center_subphy_adll[sybphy_id];
+				DEBUG_TRAINING_IP_ENGINE
+					(DEBUG_LEVEL_TRACE,
+					 ("if_id %d sybphy_id %d min center %d max center %d center %d\n",
+					 if_id, sybphy_id, min_center_subphy_adll[sybphy_id],
+					 max_center_subphy_adll[sybphy_id],
+					 center_subphy_adll_window[sybphy_id]));
+			}
+		}
+		/*
+			* check byte state and fix bits state if needed
+			* in case the level 1 and 2 above subphy results are
+			* homogeneous continue to the next subphy
+			*/
+		for (sybphy_id = 0; sybphy_id < octets_per_if_num; sybphy_id++) {
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, sybphy_id);
+			if ((byte_status[if_id][sybphy_id] == BYTE_HOMOGENEOUS_LOW) ||
+			    (byte_status[if_id][sybphy_id] == BYTE_HOMOGENEOUS_HIGH) ||
+			    (byte_status[if_id][sybphy_id] == BYTE_HOMOGENEOUS_SPLIT_IN) ||
+			    (byte_status[if_id][sybphy_id] == BYTE_HOMOGENEOUS_SPLIT_OUT) ||
+			    (byte_status[if_id][sybphy_id] == BYTE_NOT_DEFINED))
+			continue;
+
+			/*
+			 * in case all of the bits in the current subphy are
+			 * less than 32 which will find alignment in the subphy bits
+			 * mark this subphy as homogeneous split in
+			*/
+			if (center_subphy_adll_window[sybphy_id] <= 31)
+				byte_status[if_id][sybphy_id] = BYTE_HOMOGENEOUS_SPLIT_IN;
+
+			/*
+				* in case the current byte is split_out and the center is bigger than 31
+				* the byte can be aligned. in this case add 64 to the the low ui bits aligning it
+				* to the other ui bits
+				*/
+			if (center_subphy_adll_window[sybphy_id] >= 32) {
+				byte_status[if_id][sybphy_id] = BYTE_SPLIT_OUT_MIX;
+
+				DEBUG_TRAINING_IP_ENGINE
+					(DEBUG_LEVEL_TRACE,
+					 ("if_id %d sybphy_id %d byte state 0x%x\n",
+					 if_id, sybphy_id, byte_status[if_id][sybphy_id]));
+				for (bit_id = 0; bit_id < bit_end; bit_id++) {
+					if (bit_state[sybphy_id * BUS_WIDTH_IN_BITS + bit_id] == BIT_LOW_UI) {
+						l2h_if_train_res[sybphy_id * BUS_WIDTH_IN_BITS + bit_id] += 64;
+						h2l_if_train_res[sybphy_id * BUS_WIDTH_IN_BITS + bit_id] += 64;
+					}
+					DEBUG_TRAINING_IP_ENGINE
+						(DEBUG_LEVEL_TRACE,
+						 ("if_id %d sybphy_id %d bit_id %d added 64 adlls\n",
+						 if_id, sybphy_id, bit_id));
 				}
 			}
-		}		/* if bit_bit_mask_active */
-	}			/* For all Interfacess */
+		}
+	} /* for all interfaces */
 
 	return MV_OK;
 }
 
+u8 mv_ddr_tip_sub_phy_byte_status_get(u32 if_id, u32 subphy_id)
+{
+	return byte_status[if_id][subphy_id];
+}
+
+void mv_ddr_tip_sub_phy_byte_status_set(u32 if_id, u32 subphy_id, u8 byte_status_data)
+{
+	byte_status[if_id][subphy_id] = byte_status_data;
+}
+
 /*
  * Load phy values
  */
 int ddr3_tip_load_phy_values(int b_load)
 {
 	u32 bus_cnt = 0, if_id, dev_num = 0;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-		for (bus_cnt = 0; bus_cnt < GET_TOPOLOGY_NUM_OF_BUSES();
-		     bus_cnt++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+		for (bus_cnt = 0; bus_cnt < octets_per_if_num; bus_cnt++) {
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_cnt);
 			if (b_load == 1) {
 				CHECK_STATUS(ddr3_tip_bus_read
 					     (dev_num, if_id,
 					      ACCESS_TYPE_UNICAST, bus_cnt,
 					      DDR_PHY_DATA,
-					      WRITE_CENTRALIZATION_PHY_REG +
-					      (effective_cs *
-					       CS_REGISTER_ADDR_OFFSET),
+					      CTX_PHY_REG(effective_cs),
 					      &phy_reg_bk[if_id][bus_cnt]
 					      [0]));
 				CHECK_STATUS(ddr3_tip_bus_read
 					     (dev_num, if_id,
 					      ACCESS_TYPE_UNICAST, bus_cnt,
 					      DDR_PHY_DATA,
-					      RL_PHY_REG +
-					      (effective_cs *
-					       CS_REGISTER_ADDR_OFFSET),
+					      RL_PHY_REG(effective_cs),
 					      &phy_reg_bk[if_id][bus_cnt]
 					      [1]));
 				CHECK_STATUS(ddr3_tip_bus_read
 					     (dev_num, if_id,
 					      ACCESS_TYPE_UNICAST, bus_cnt,
 					      DDR_PHY_DATA,
-					      READ_CENTRALIZATION_PHY_REG +
-					      (effective_cs *
-					       CS_REGISTER_ADDR_OFFSET),
+					      CRX_PHY_REG(effective_cs),
 					      &phy_reg_bk[if_id][bus_cnt]
 					      [2]));
 			} else {
@@ -1216,27 +1491,21 @@ int ddr3_tip_load_phy_values(int b_load)
 					     (dev_num, ACCESS_TYPE_UNICAST,
 					      if_id, ACCESS_TYPE_UNICAST,
 					      bus_cnt, DDR_PHY_DATA,
-					      WRITE_CENTRALIZATION_PHY_REG +
-					      (effective_cs *
-					       CS_REGISTER_ADDR_OFFSET),
+					      CTX_PHY_REG(effective_cs),
 					      phy_reg_bk[if_id][bus_cnt]
 					      [0]));
 				CHECK_STATUS(ddr3_tip_bus_write
 					     (dev_num, ACCESS_TYPE_UNICAST,
 					      if_id, ACCESS_TYPE_UNICAST,
 					      bus_cnt, DDR_PHY_DATA,
-					      RL_PHY_REG +
-					      (effective_cs *
-					       CS_REGISTER_ADDR_OFFSET),
+					      RL_PHY_REG(effective_cs),
 					      phy_reg_bk[if_id][bus_cnt]
 					      [1]));
 				CHECK_STATUS(ddr3_tip_bus_write
 					     (dev_num, ACCESS_TYPE_UNICAST,
 					      if_id, ACCESS_TYPE_UNICAST,
 					      bus_cnt, DDR_PHY_DATA,
-					      READ_CENTRALIZATION_PHY_REG +
-					      (effective_cs *
-					       CS_REGISTER_ADDR_OFFSET),
+					      CRX_PHY_REG(effective_cs),
 					      phy_reg_bk[if_id][bus_cnt]
 					      [2]));
 			}
@@ -1258,7 +1527,8 @@ int ddr3_tip_training_ip_test(u32 dev_num, enum hws_training_result result_type,
 	enum hws_training_ip_stat train_status[MAX_INTERFACE_NUM];
 	u32 *res = NULL;
 	u32 search_state = 0;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	ddr3_tip_load_phy_values(1);
 
@@ -1280,11 +1550,11 @@ int ddr3_tip_training_ip_test(u32 dev_num, enum hws_training_result result_type,
 
 			for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
 			     if_id++) {
-				VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+				VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 				for (pup_id = 0; pup_id <
-					     tm->num_of_bus_per_interface;
+					     octets_per_if_num;
 				     pup_id++) {
-					VALIDATE_ACTIVE(tm->bus_act_mask,
+					VALIDATE_BUS_ACTIVE(tm->bus_act_mask,
 							pup_id);
 					CHECK_STATUS
 						(ddr3_tip_read_training_result
@@ -1323,11 +1593,20 @@ int ddr3_tip_training_ip_test(u32 dev_num, enum hws_training_result result_type,
 	return MV_OK;
 }
 
+int mv_ddr_pattern_start_addr_set(struct pattern_info *pattern_tbl, enum hws_pattern pattern, u32 addr)
+{
+	pattern_tbl[pattern].start_addr = addr;
+
+	return 0;
+}
+
 struct pattern_info *ddr3_tip_get_pattern_table()
 {
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
-	if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask) == 0)
+	if (MV_DDR_IS_64BIT_DRAM_MODE(tm->bus_act_mask))
+		return pattern_table_64;
+	else if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask) == 0)
 		return pattern_table_32;
 	else
 		return pattern_table_16;
@@ -1335,20 +1614,63 @@ struct pattern_info *ddr3_tip_get_pattern_table()
 
 u16 *ddr3_tip_get_mask_results_dq_reg()
 {
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+#if MAX_BUS_NUM == 5
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	if (DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask))
 		return mask_results_dq_reg_map_pup3_ecc;
 	else
+#endif
 		return mask_results_dq_reg_map;
 }
 
 u16 *ddr3_tip_get_mask_results_pup_reg_map()
 {
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+#if MAX_BUS_NUM == 5
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	if (DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask))
 		return mask_results_pup_reg_map_pup3_ecc;
 	else
+#endif
 		return mask_results_pup_reg_map;
 }
+
+/* load expected dm pattern to odpg */
+#define LOW_NIBBLE_BYTE_MASK	0xf
+#define HIGH_NIBBLE_BYTE_MASK	0xf0
+int mv_ddr_load_dm_pattern_to_odpg(enum hws_access_type access_type, enum hws_pattern pattern,
+				   enum dm_direction dm_dir)
+{
+	struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+	u32 pattern_len = 0;
+	u32 data_low, data_high;
+	u8 dm_data;
+
+	for (pattern_len = 0;
+	     pattern_len < pattern_table[pattern].pattern_len;
+	     pattern_len++) {
+		if (MV_DDR_IS_64BIT_DRAM_MODE(tm->bus_act_mask)) {
+			data_low = pattern_table_get_word(0, pattern, (u8)pattern_len);
+			data_high = data_low;
+		} else {
+			data_low = pattern_table_get_word(0, pattern, (u8)(pattern_len * 2));
+			data_high = pattern_table_get_word(0, pattern, (u8)(pattern_len * 2 + 1));
+		}
+
+		/* odpg mbus dm definition is opposite to ddr4 protocol */
+		if (dm_dir == DM_DIR_INVERSE)
+			dm_data = ~((data_low & LOW_NIBBLE_BYTE_MASK) | (data_high & HIGH_NIBBLE_BYTE_MASK));
+		else
+			dm_data = (data_low & LOW_NIBBLE_BYTE_MASK) | (data_high & HIGH_NIBBLE_BYTE_MASK);
+
+		ddr3_tip_if_write(0, access_type, 0, ODPG_DATA_WR_DATA_LOW_REG, data_low, MASK_ALL_BITS);
+		ddr3_tip_if_write(0, access_type, 0, ODPG_DATA_WR_DATA_HIGH_REG, data_high, MASK_ALL_BITS);
+		ddr3_tip_if_write(0, access_type, 0, ODPG_DATA_WR_ADDR_REG,
+				  pattern_len | ((dm_data & ODPG_DATA_WR_DATA_MASK) << ODPG_DATA_WR_DATA_OFFS),
+				  MASK_ALL_BITS);
+	}
+
+	return MV_OK;
+}
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.h b/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.h
index 25b146216ecd..f2e651bc06d5 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.h
+++ b/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.h
@@ -38,8 +38,6 @@ int ddr3_tip_training_ip_test(u32 dev_num, enum hws_training_result result_type,
 			      u32 num_of_iterations, u32 start_pattern,
 			      u32 end_pattern);
 int ddr3_tip_load_pattern_to_mem(u32 dev_num, enum hws_pattern pattern);
-int ddr3_tip_load_pattern_to_mem_by_cpu(u32 dev_num, enum hws_pattern pattern,
-					u32 offset);
 int ddr3_tip_load_all_pattern_to_mem(u32 dev_num);
 int ddr3_tip_read_training_result(u32 dev_num, u32 if_id,
 				  enum hws_access_type pup_access_type,
@@ -76,10 +74,13 @@ int ddr3_tip_ip_training_wrapper(u32 dev_num, enum hws_access_type access_type,
 				 enum hws_edge_compare edge_comp,
 				 enum hws_ddr_cs train_cs_type, u32 cs_num,
 				 enum hws_training_ip_stat *train_status);
-int is_odpg_access_done(u32 dev_num, u32 if_id);
+u8 mv_ddr_tip_sub_phy_byte_status_get(u32 if_id, u32 subphy_id);
+void mv_ddr_tip_sub_phy_byte_status_set(u32 if_id, u32 subphy_id, u8 byte_status_data);
 void ddr3_tip_print_bist_res(void);
 struct pattern_info *ddr3_tip_get_pattern_table(void);
 u16 *ddr3_tip_get_mask_results_dq_reg(void);
 u16 *ddr3_tip_get_mask_results_pup_reg_map(void);
-
+int mv_ddr_load_dm_pattern_to_odpg(enum hws_access_type access_type, enum hws_pattern pattern,
+				   enum dm_direction dm_dir);
+int mv_ddr_pattern_start_addr_set(struct pattern_info *pattern_tbl, enum hws_pattern pattern, u32 addr);
 #endif /* _DDR3_TRAINING_IP_ENGINE_H_ */
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip_flow.h b/drivers/ddr/marvell/a38x/ddr3_training_ip_flow.h
index 22d7ce23e61e..14af632cffea 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training_ip_flow.h
+++ b/drivers/ddr/marvell/a38x/ddr3_training_ip_flow.h
@@ -9,45 +9,73 @@
 
 #include "ddr3_training_ip.h"
 #include "ddr3_training_ip_pbs.h"
-
-#define MRS0_CMD			0x3
-#define MRS1_CMD			0x4
-#define MRS2_CMD			0x8
-#define MRS3_CMD			0x9
-
-/*
- * Definitions of INTERFACE registers
- */
-
-#define READ_BUFFER_SELECT		0x14a4
-
-/*
- * Definitions of PHY registers
- */
+#include "mv_ddr_regs.h"
 
 #define KILLER_PATTERN_LENGTH		32
 #define EXT_ACCESS_BURST_LENGTH		8
 
-#define IS_ACTIVE(if_mask , if_id) \
-	((if_mask) & (1 << (if_id)))
+#define IS_ACTIVE(mask, id) \
+	((mask) & (1 << (id)))
+
 #define VALIDATE_ACTIVE(mask, id)		\
 	{					\
 	if (IS_ACTIVE(mask, id) == 0)		\
 		continue;			\
 	}
 
-#define GET_TOPOLOGY_NUM_OF_BUSES() \
-	(ddr3_get_topology_map()->num_of_bus_per_interface)
+#define IS_IF_ACTIVE(if_mask, if_id) \
+	((if_mask) & (1 << (if_id)))
+
+#define VALIDATE_IF_ACTIVE(mask, id)		\
+	{					\
+	if (IS_IF_ACTIVE(mask, id) == 0)	\
+		continue;			\
+	}
+
+#define IS_BUS_ACTIVE(if_mask , if_id) \
+	(((if_mask) >> (if_id)) & 1)
+
+#define VALIDATE_BUS_ACTIVE(mask, id)		\
+	{					\
+	if (IS_BUS_ACTIVE(mask, id) == 0)	\
+		continue;			\
+	}
 
 #define DDR3_IS_ECC_PUP3_MODE(if_mask) \
-	(((if_mask) == 0xb) ? 1 : 0)
+	(((if_mask) == BUS_MASK_16BIT_ECC_PUP3) ? 1 : 0)
+
 #define DDR3_IS_ECC_PUP4_MODE(if_mask) \
-	(((((if_mask) & 0x10) == 0)) ? 0 : 1)
+	((if_mask == BUS_MASK_32BIT_ECC || if_mask == BUS_MASK_16BIT_ECC) ? 1 : 0)
+
 #define DDR3_IS_16BIT_DRAM_MODE(mask) \
-	(((((mask) & 0x4) == 0)) ? 1 : 0)
+	((mask == BUS_MASK_16BIT || mask == BUS_MASK_16BIT_ECC || mask == BUS_MASK_16BIT_ECC_PUP3) ? 1 : 0)
 
+#define DDR3_IS_ECC_PUP8_MODE(if_mask) \
+	((if_mask == MV_DDR_32BIT_ECC_PUP8_BUS_MASK || if_mask == MV_DDR_64BIT_ECC_PUP8_BUS_MASK) ? 1 : 0)
+
+#define MV_DDR_IS_64BIT_DRAM_MODE(mask) \
+	((((mask) & MV_DDR_64BIT_BUS_MASK) == MV_DDR_64BIT_BUS_MASK) || \
+	(((mask) & MV_DDR_64BIT_ECC_PUP8_BUS_MASK) == MV_DDR_64BIT_ECC_PUP8_BUS_MASK) ? 1 : 0)
+
+#define MV_DDR_IS_32BIT_IN_64BIT_DRAM_MODE(mask, octets_per_if_num/* FIXME: get from ATF */) \
+	((octets_per_if_num == 9/* FIXME: get from ATF */) && \
+	((mask == BUS_MASK_32BIT) || \
+	(mask == MV_DDR_32BIT_ECC_PUP8_BUS_MASK)) ? 1 : 0)
+
+#define MV_DDR_IS_HALF_BUS_DRAM_MODE(mask, octets_per_if_num/* FIXME: get from ATF */) \
+	(MV_DDR_IS_32BIT_IN_64BIT_DRAM_MODE(mask, octets_per_if_num) || DDR3_IS_16BIT_DRAM_MODE(mask))
+
+#define ECC_READ_BUS_0			0
+#define ECC_PHY_ACCESS_3		3
+#define ECC_PHY_ACCESS_4		4
+#define ECC_PHY_ACCESS_8		8
 #define MEGA				1000000
 #define BUS_WIDTH_IN_BITS		8
+#define MAX_POLLING_ITERATIONS		1000000
+#define NUM_OF_CS			4
+#define ADLL_LENGTH			32
+
+#define GP_RSVD0_REG			0x182e0
 
 /*
  * DFX address Space
@@ -67,205 +95,20 @@
 /* nsec */
 #define  TREFI_LOW				7800
 #define  TREFI_HIGH				3900
+#define AUTO_ZQC_TIMING				15384
+
+enum mr_number {
+	MR_CMD0,
+	MR_CMD1,
+	MR_CMD2,
+	MR_CMD3,
+	MR_LAST
+};
 
-#define  TR2R_VALUE_REG				0x180
-#define  TR2R_MASK_REG				0x180
-#define  TRFC_MASK_REG				0x7f
-#define  TR2W_MASK_REG				0x600
-#define  TW2W_HIGH_VALUE_REG			0x1800
-#define  TW2W_HIGH_MASK_REG			0xf800
-#define  TRFC_HIGH_VALUE_REG			0x20000
-#define  TRFC_HIGH_MASK_REG			0x70000
-#define  TR2R_HIGH_VALUE_REG			0x0
-#define  TR2R_HIGH_MASK_REG			0x380000
-#define  TMOD_VALUE_REG				0x16000000
-#define  TMOD_MASK_REG				0x1e000000
-#define  T_VALUE_REG				0x40000000
-#define  T_MASK_REG				0xc0000000
-#define  AUTO_ZQC_TIMING			15384
-#define  WRITE_XBAR_PORT1			0xc03f8077
-#define  READ_XBAR_PORT1			0xc03f8073
-#define  DISABLE_DDR_TUNING_DATA		0x02294285
-#define  ENABLE_DDR_TUNING_DATA			0x12294285
-
-#define ODPG_TRAINING_STATUS_REG		0x18488
-#define ODPG_TRAINING_TRIGGER_REG		0x1030
-#define ODPG_STATUS_DONE_REG			0x16fc
-#define ODPG_ENABLE_REG				0x186d4
-#define ODPG_ENABLE_OFFS			0
-#define ODPG_DISABLE_OFFS			8
-
-#define ODPG_TRAINING_CONTROL_REG		0x1034
-#define ODPG_OBJ1_OPCODE_REG			0x103c
-#define ODPG_OBJ1_ITER_CNT_REG			0x10b4
-#define CALIB_OBJ_PRFA_REG			0x10c4
-#define ODPG_WRITE_LEVELING_DONE_CNTR_REG	0x10f8
-#define ODPG_WRITE_READ_MODE_ENABLE_REG		0x10fc
-#define TRAINING_OPCODE_1_REG			0x10b4
-#define SDRAM_CONFIGURATION_REG			0x1400
-#define DDR_CONTROL_LOW_REG			0x1404
-#define SDRAM_TIMING_LOW_REG			0x1408
-#define SDRAM_TIMING_HIGH_REG			0x140c
-#define SDRAM_ACCESS_CONTROL_REG		0x1410
-#define SDRAM_OPEN_PAGE_CONTROL_REG		0x1414
-#define SDRAM_OPERATION_REG			0x1418
-#define DUNIT_CONTROL_HIGH_REG			0x1424
-#define ODT_TIMING_LOW				0x1428
-#define DDR_TIMING_REG				0x142c
-#define ODT_TIMING_HI_REG			0x147c
-#define SDRAM_INIT_CONTROL_REG			0x1480
-#define SDRAM_ODT_CONTROL_HIGH_REG		0x1498
-#define DUNIT_ODT_CONTROL_REG			0x149c
-#define READ_BUFFER_SELECT_REG			0x14a4
-#define DUNIT_MMASK_REG				0x14b0
-#define CALIB_MACHINE_CTRL_REG			0x14cc
-#define DRAM_DLL_TIMING_REG			0x14e0
-#define DRAM_ZQ_INIT_TIMIMG_REG			0x14e4
-#define DRAM_ZQ_TIMING_REG			0x14e8
-#define DFS_REG					0x1528
-#define READ_DATA_SAMPLE_DELAY			0x1538
-#define READ_DATA_READY_DELAY			0x153c
-#define TRAINING_REG				0x15b0
-#define TRAINING_SW_1_REG			0x15b4
-#define TRAINING_SW_2_REG			0x15b8
-#define TRAINING_PATTERN_BASE_ADDRESS_REG	0x15bc
-#define TRAINING_DBG_1_REG			0x15c0
-#define TRAINING_DBG_2_REG			0x15c4
-#define TRAINING_DBG_3_REG			0x15c8
-#define RANK_CTRL_REG				0x15e0
-#define TIMING_REG				0x15e4
-#define DRAM_PHY_CONFIGURATION			0x15ec
-#define MR0_REG					0x15d0
-#define MR1_REG					0x15d4
-#define MR2_REG					0x15d8
-#define MR3_REG					0x15dc
-#define TIMING_REG				0x15e4
-#define ODPG_CTRL_CONTROL_REG			0x1600
-#define ODPG_DATA_CONTROL_REG			0x1630
-#define ODPG_PATTERN_ADDR_OFFSET_REG		0x1638
-#define ODPG_DATA_BUF_SIZE_REG			0x163c
-#define PHY_LOCK_STATUS_REG			0x1674
-#define PHY_REG_FILE_ACCESS			0x16a0
-#define TRAINING_WRITE_LEVELING_REG		0x16ac
-#define ODPG_PATTERN_ADDR_REG			0x16b0
-#define ODPG_PATTERN_DATA_HI_REG		0x16b4
-#define ODPG_PATTERN_DATA_LOW_REG		0x16b8
-#define ODPG_BIST_LAST_FAIL_ADDR_REG		0x16bc
-#define ODPG_BIST_DATA_ERROR_COUNTER_REG	0x16c0
-#define ODPG_BIST_FAILED_DATA_HI_REG		0x16c4
-#define ODPG_BIST_FAILED_DATA_LOW_REG		0x16c8
-#define ODPG_WRITE_DATA_ERROR_REG		0x16cc
-#define CS_ENABLE_REG				0x16d8
-#define WR_LEVELING_DQS_PATTERN_REG		0x16dc
-
-#define ODPG_BIST_DONE				0x186d4
-#define ODPG_BIST_DONE_BIT_OFFS			0
-#define ODPG_BIST_DONE_BIT_VALUE		0
-
-#define RESULT_CONTROL_BYTE_PUP_0_REG		0x1830
-#define RESULT_CONTROL_BYTE_PUP_1_REG		0x1834
-#define RESULT_CONTROL_BYTE_PUP_2_REG		0x1838
-#define RESULT_CONTROL_BYTE_PUP_3_REG		0x183c
-#define RESULT_CONTROL_BYTE_PUP_4_REG		0x18b0
-
-#define RESULT_CONTROL_PUP_0_BIT_0_REG		0x18b4
-#define RESULT_CONTROL_PUP_0_BIT_1_REG		0x18b8
-#define RESULT_CONTROL_PUP_0_BIT_2_REG		0x18bc
-#define RESULT_CONTROL_PUP_0_BIT_3_REG		0x18c0
-#define RESULT_CONTROL_PUP_0_BIT_4_REG		0x18c4
-#define RESULT_CONTROL_PUP_0_BIT_5_REG		0x18c8
-#define RESULT_CONTROL_PUP_0_BIT_6_REG		0x18cc
-#define RESULT_CONTROL_PUP_0_BIT_7_REG		0x18f0
-#define RESULT_CONTROL_PUP_1_BIT_0_REG		0x18f4
-#define RESULT_CONTROL_PUP_1_BIT_1_REG		0x18f8
-#define RESULT_CONTROL_PUP_1_BIT_2_REG		0x18fc
-#define RESULT_CONTROL_PUP_1_BIT_3_REG		0x1930
-#define RESULT_CONTROL_PUP_1_BIT_4_REG		0x1934
-#define RESULT_CONTROL_PUP_1_BIT_5_REG		0x1938
-#define RESULT_CONTROL_PUP_1_BIT_6_REG		0x193c
-#define RESULT_CONTROL_PUP_1_BIT_7_REG		0x19b0
-#define RESULT_CONTROL_PUP_2_BIT_0_REG		0x19b4
-#define RESULT_CONTROL_PUP_2_BIT_1_REG		0x19b8
-#define RESULT_CONTROL_PUP_2_BIT_2_REG		0x19bc
-#define RESULT_CONTROL_PUP_2_BIT_3_REG		0x19c0
-#define RESULT_CONTROL_PUP_2_BIT_4_REG		0x19c4
-#define RESULT_CONTROL_PUP_2_BIT_5_REG		0x19c8
-#define RESULT_CONTROL_PUP_2_BIT_6_REG		0x19cc
-#define RESULT_CONTROL_PUP_2_BIT_7_REG		0x19f0
-#define RESULT_CONTROL_PUP_3_BIT_0_REG		0x19f4
-#define RESULT_CONTROL_PUP_3_BIT_1_REG		0x19f8
-#define RESULT_CONTROL_PUP_3_BIT_2_REG		0x19fc
-#define RESULT_CONTROL_PUP_3_BIT_3_REG		0x1a30
-#define RESULT_CONTROL_PUP_3_BIT_4_REG		0x1a34
-#define RESULT_CONTROL_PUP_3_BIT_5_REG		0x1a38
-#define RESULT_CONTROL_PUP_3_BIT_6_REG		0x1a3c
-#define RESULT_CONTROL_PUP_3_BIT_7_REG		0x1ab0
-#define RESULT_CONTROL_PUP_4_BIT_0_REG		0x1ab4
-#define RESULT_CONTROL_PUP_4_BIT_1_REG		0x1ab8
-#define RESULT_CONTROL_PUP_4_BIT_2_REG		0x1abc
-#define RESULT_CONTROL_PUP_4_BIT_3_REG		0x1ac0
-#define RESULT_CONTROL_PUP_4_BIT_4_REG		0x1ac4
-#define RESULT_CONTROL_PUP_4_BIT_5_REG		0x1ac8
-#define RESULT_CONTROL_PUP_4_BIT_6_REG		0x1acc
-#define RESULT_CONTROL_PUP_4_BIT_7_REG		0x1af0
-
-#define WL_PHY_REG				0x0
-#define WRITE_CENTRALIZATION_PHY_REG		0x1
-#define RL_PHY_REG				0x2
-#define READ_CENTRALIZATION_PHY_REG		0x3
-#define PBS_RX_PHY_REG				0x50
-#define PBS_TX_PHY_REG				0x10
-#define PHY_CONTROL_PHY_REG			0x90
-#define BW_PHY_REG				0x92
-#define RATE_PHY_REG				0x94
-#define CMOS_CONFIG_PHY_REG			0xa2
-#define PAD_ZRI_CALIB_PHY_REG			0xa4
-#define PAD_ODT_CALIB_PHY_REG			0xa6
-#define PAD_CONFIG_PHY_REG			0xa8
-#define PAD_PRE_DISABLE_PHY_REG			0xa9
-#define TEST_ADLL_REG				0xbf
-#define CSN_IOB_VREF_REG(cs)			(0xdb + (cs * 12))
-#define CSN_IO_BASE_VREF_REG(cs)		(0xd0 + (cs * 12))
-
-#define RESULT_DB_PHY_REG_ADDR			0xc0
-#define RESULT_DB_PHY_REG_RX_OFFSET		5
-#define RESULT_DB_PHY_REG_TX_OFFSET		0
-
-/* TBD - for NP5 use only CS 0 */
-#define PHY_WRITE_DELAY(cs)			WL_PHY_REG
-/*( ( _cs_ == 0 ) ? 0x0 : 0x4 )*/
-/* TBD - for NP5 use only CS 0 */
-#define PHY_READ_DELAY(cs)			RL_PHY_REG
-
-#define DDR0_ADDR_1				0xf8258
-#define DDR0_ADDR_2				0xf8254
-#define DDR1_ADDR_1				0xf8270
-#define DDR1_ADDR_2				0xf8270
-#define DDR2_ADDR_1				0xf825c
-#define DDR2_ADDR_2				0xf825c
-#define DDR3_ADDR_1				0xf8264
-#define DDR3_ADDR_2				0xf8260
-#define DDR4_ADDR_1				0xf8274
-#define DDR4_ADDR_2				0xf8274
-
-#define GENERAL_PURPOSE_RESERVED0_REG		0x182e0
-
-#define GET_BLOCK_ID_MAX_FREQ(dev_num, block_id)	800000
-#define CS0_RD_LVL_REF_DLY_OFFS			0
-#define CS0_RD_LVL_REF_DLY_LEN			0
-#define CS0_RD_LVL_PH_SEL_OFFS			0
-#define CS0_RD_LVL_PH_SEL_LEN			0
-
-#define CS_REGISTER_ADDR_OFFSET			4
-#define CALIBRATED_OBJECTS_REG_ADDR_OFFSET	0x10
-
-#define MAX_POLLING_ITERATIONS			100000
-
-#define PHASE_REG_OFFSET			32
-#define NUM_BYTES_IN_BURST			31
-#define NUM_OF_CS				4
-#define CS_REG_VALUE(cs_num)			(cs_mask_reg[cs_num])
-#define ADLL_LENGTH				32
+struct mv_ddr_mr_data {
+	u32 cmd;
+	u32 reg_addr;
+};
 
 struct write_supp_result {
 	enum hws_wl_supp stage;
@@ -315,10 +158,11 @@ int ddr3_tip_ext_read(u32 dev_num, u32 if_id, u32 reg_addr,
 int ddr3_tip_ext_write(u32 dev_num, u32 if_id, u32 reg_addr,
 		       u32 num_of_bursts, u32 *addr);
 int ddr3_tip_dynamic_read_leveling(u32 dev_num, u32 ui_freq);
+int mv_ddr_rl_dqs_burst(u32 dev_num, u32 if_id, u32 freq);
 int ddr3_tip_legacy_dynamic_read_leveling(u32 dev_num);
 int ddr3_tip_dynamic_per_bit_read_leveling(u32 dev_num, u32 ui_freq);
 int ddr3_tip_legacy_dynamic_write_leveling(u32 dev_num);
-int ddr3_tip_dynamic_write_leveling(u32 dev_num);
+int ddr3_tip_dynamic_write_leveling(u32 dev_num, int phase_remove);
 int ddr3_tip_dynamic_write_leveling_supp(u32 dev_num);
 int ddr3_tip_static_init_controller(u32 dev_num);
 int ddr3_tip_configure_phy(u32 dev_num);
@@ -332,18 +176,21 @@ int ddr3_tip_configure_odpg(u32 dev_num, enum hws_access_type access_type,
 			    u32 delay_between_burst, u32 rd_mode, u32 cs_num,
 			    u32 addr_stress_jump, u32 single_pattern);
 int ddr3_tip_set_atr(u32 dev_num, u32 flag_id, u32 value);
-int ddr3_tip_write_mrs_cmd(u32 dev_num, u32 *cs_mask_arr, u32 cmd, u32 data,
-			   u32 mask);
+int ddr3_tip_write_mrs_cmd(u32 dev_num, u32 *cs_mask_arr, enum mr_number mr_num, u32 data, u32 mask);
 int ddr3_tip_write_cs_result(u32 dev_num, u32 offset);
 int ddr3_tip_get_first_active_if(u8 dev_num, u32 interface_mask, u32 *if_id);
 int ddr3_tip_reset_fifo_ptr(u32 dev_num);
-int read_pup_value(int pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
-		   int reg_addr, u32 mask);
-int read_adll_value(u32 pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
-		    int reg_addr, u32 mask);
-int write_adll_value(u32 pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
-		     int reg_addr);
+int ddr3_tip_read_pup_value(u32 dev_num,
+			    u32 pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
+			    int reg_addr, u32 mask);
+int ddr3_tip_read_adll_value(u32 dev_num,
+			     u32 pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
+			     u32 reg_addr, u32 mask);
+int ddr3_tip_write_adll_value(u32 dev_num,
+			      u32 pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
+			      u32 reg_addr);
 int ddr3_tip_tune_training_params(u32 dev_num,
 				  struct tune_train_params *params);
+struct page_element *mv_ddr_page_tbl_get(void);
 
 #endif /* _DDR3_TRAINING_IP_FLOW_H_ */
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip_prv_if.h b/drivers/ddr/marvell/a38x/ddr3_training_ip_prv_if.h
index 724b1062754f..5cf347750e3e 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training_ip_prv_if.h
+++ b/drivers/ddr/marvell/a38x/ddr3_training_ip_prv_if.h
@@ -63,7 +63,7 @@ typedef int (*HWS_TRAINING_IP_PBS_TX_FUNC_PTR)(u32 dev_num);
 typedef int (*HWS_TRAINING_IP_SELECT_CONTROLLER_FUNC_PTR)(
 	u32 dev_num, int enable);
 typedef int (*HWS_TRAINING_IP_TOPOLOGY_MAP_LOAD_FUNC_PTR)(
-	u32 dev_num, struct hws_topology_map *topology_map);
+	u32 dev_num, struct mv_ddr_topology_map *tm);
 typedef int (*HWS_TRAINING_IP_STATIC_CONFIG_FUNC_PTR)(
 	u32 dev_num, enum hws_ddr_freq frequency,
 	enum hws_static_config_type static_config_type, u32 if_id);
@@ -84,16 +84,27 @@ typedef int (*HWS_TRAINING_IP_LOAD_TOPOLOGY)(u32 dev_num, u32 config_num);
 typedef int (*HWS_TRAINING_IP_READ_LEVELING)(u32 dev_num, u32 config_num);
 typedef int (*HWS_TRAINING_IP_WRITE_LEVELING)(u32 dev_num, u32 config_num);
 typedef u32 (*HWS_TRAINING_IP_GET_TEMP)(u8 dev_num);
+typedef u8 (*HWS_TRAINING_IP_GET_RATIO)(u32 freq);
 
 struct hws_tip_config_func_db {
 	HWS_TIP_DUNIT_MUX_SELECT_FUNC_PTR tip_dunit_mux_select_func;
-	HWS_TIP_DUNIT_REG_READ_FUNC_PTR tip_dunit_read_func;
-	HWS_TIP_DUNIT_REG_WRITE_FUNC_PTR tip_dunit_write_func;
+	void (*mv_ddr_dunit_read)(u32 addr, u32 mask, u32 *data);
+	void (*mv_ddr_dunit_write)(u32 addr, u32 mask, u32 data);
 	HWS_TIP_GET_FREQ_CONFIG_INFO tip_get_freq_config_info_func;
 	HWS_TIP_GET_DEVICE_INFO tip_get_device_info_func;
 	HWS_SET_FREQ_DIVIDER_FUNC_PTR tip_set_freq_divider_func;
 	HWS_GET_CS_CONFIG_FUNC_PTR tip_get_cs_config_info;
 	HWS_TRAINING_IP_GET_TEMP tip_get_temperature;
+	HWS_TRAINING_IP_GET_RATIO tip_get_clock_ratio;
+	HWS_TRAINING_IP_EXTERNAL_READ_PTR tip_external_read;
+	HWS_TRAINING_IP_EXTERNAL_WRITE_PTR tip_external_write;
+	int (*mv_ddr_phy_read)(enum hws_access_type phy_access,
+			       u32 phy, enum hws_ddr_phy phy_type,
+			       u32 reg_addr, u32 *data);
+	int (*mv_ddr_phy_write)(enum hws_access_type phy_access,
+				u32 phy, enum hws_ddr_phy phy_type,
+				u32 reg_addr, u32 data,
+				enum hws_operation op_type);
 };
 
 int ddr3_tip_init_config_func(u32 dev_num,
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip_static.h b/drivers/ddr/marvell/a38x/ddr3_training_ip_static.h
deleted file mode 100644
index 878068b24d7a..000000000000
--- a/drivers/ddr/marvell/a38x/ddr3_training_ip_static.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- *
- * SPDX-License-Identifier:	GPL-2.0
- */
-
-#ifndef _DDR3_TRAINING_IP_STATIC_H_
-#define _DDR3_TRAINING_IP_STATIC_H_
-
-#include "ddr3_training_ip_def.h"
-#include "ddr3_training_ip.h"
-
-struct trip_delay_element {
-	u32 dqs_delay;		/* DQS delay (m_sec) */
-	u32 ck_delay;		/* CK Delay  (m_sec) */
-};
-
-struct hws_tip_static_config_info {
-	u32 silicon_delay;
-	struct trip_delay_element *package_trace_arr;
-	struct trip_delay_element *board_trace_arr;
-};
-
-int ddr3_tip_run_static_alg(u32 dev_num, enum hws_ddr_freq freq);
-int ddr3_tip_init_static_config_db(
-	u32 dev_num, struct hws_tip_static_config_info *static_config_info);
-int ddr3_tip_init_specific_reg_config(u32 dev_num,
-				      struct reg_data *reg_config_arr);
-int ddr3_tip_static_phy_init_controller(u32 dev_num);
-
-#endif /* _DDR3_TRAINING_IP_STATIC_H_ */
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_leveling.c b/drivers/ddr/marvell/a38x/ddr3_training_leveling.c
index 3c40f198e775..96dc6600f095 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training_leveling.c
+++ b/drivers/ddr/marvell/a38x/ddr3_training_leveling.c
@@ -4,17 +4,9 @@
  * SPDX-License-Identifier:	GPL-2.0
  */
 
-#include <common.h>
-#include <spl.h>
-#include <asm/io.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/soc.h>
-
 #include "ddr3_init.h"
 
-#define WL_ITERATION_NUM		10
-#define ONE_CLOCK_ERROR_SHIFT		2
-#define ALIGN_ERROR_SHIFT		-2
+#define WL_ITERATION_NUM	10
 
 static u32 pup_mask_table[] = {
 	0x000000ff,
@@ -28,26 +20,30 @@ static struct write_supp_result wr_supp_res[MAX_INTERFACE_NUM][MAX_BUS_NUM];
 static int ddr3_tip_dynamic_write_leveling_seq(u32 dev_num);
 static int ddr3_tip_dynamic_read_leveling_seq(u32 dev_num);
 static int ddr3_tip_dynamic_per_bit_read_leveling_seq(u32 dev_num);
-static int ddr3_tip_wl_supp_align_err_shift(u32 dev_num, u32 if_id, u32 bus_id,
-					    u32 bus_id_delta);
 static int ddr3_tip_wl_supp_align_phase_shift(u32 dev_num, u32 if_id,
-					      u32 bus_id, u32 offset,
-					      u32 bus_id_delta);
+					      u32 bus_id);
 static int ddr3_tip_xsb_compare_test(u32 dev_num, u32 if_id, u32 bus_id,
-				     u32 edge_offset, u32 bus_id_delta);
-static int ddr3_tip_wl_supp_one_clk_err_shift(u32 dev_num, u32 if_id,
-					      u32 bus_id, u32 bus_id_delta);
+				     u32 edge_offset);
 
-u32 hws_ddr3_tip_max_cs_get(void)
+u32 ddr3_tip_max_cs_get(u32 dev_num)
 {
-	u32 c_cs;
+	u32 c_cs, if_id, bus_id;
 	static u32 max_cs;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
 
 	if (!max_cs) {
+		CHECK_STATUS(ddr3_tip_get_first_active_if((u8)dev_num,
+							  tm->if_act_mask,
+							  &if_id));
+		for (bus_id = 0; bus_id < octets_per_if_num; bus_id++) {
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
+			break;
+		}
+
 		for (c_cs = 0; c_cs < NUM_OF_CS; c_cs++) {
 			VALIDATE_ACTIVE(tm->
-					interface_params[0].as_bus_params[0].
+					interface_params[if_id].as_bus_params[bus_id].
 					cs_bitmask, c_cs);
 			max_cs++;
 		}
@@ -56,13 +52,17 @@ u32 hws_ddr3_tip_max_cs_get(void)
 	return max_cs;
 }
 
+enum {
+	PASS,
+	FAIL
+};
 /*****************************************************************************
 Dynamic read leveling
 ******************************************************************************/
 int ddr3_tip_dynamic_read_leveling(u32 dev_num, u32 freq)
 {
 	u32 data, mask;
-	u32 max_cs = hws_ddr3_tip_max_cs_get();
+	u32 max_cs = ddr3_tip_max_cs_get(dev_num);
 	u32 bus_num, if_id, cl_val;
 	enum hws_speed_bin speed_bin_index;
 	/* save current CS value */
@@ -72,82 +72,9 @@ int ddr3_tip_dynamic_read_leveling(u32 dev_num, u32 freq)
 	u8 rl_values[NUM_OF_CS][MAX_BUS_NUM][MAX_INTERFACE_NUM];
 	struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
 	u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
-	struct hws_topology_map *tm = ddr3_get_topology_map();
-
-	if (rl_version == 0) {
-		/* OLD RL machine */
-		data = 0x40;
-		data |= (1 << 20);
-
-		/* TBD multi CS */
-		CHECK_STATUS(ddr3_tip_if_write(
-				     dev_num, ACCESS_TYPE_MULTICAST,
-				     PARAM_NOT_CARE, TRAINING_REG,
-				     data, 0x11ffff));
-		CHECK_STATUS(ddr3_tip_if_write(
-				     dev_num, ACCESS_TYPE_MULTICAST,
-				     PARAM_NOT_CARE,
-				     TRAINING_PATTERN_BASE_ADDRESS_REG,
-				     0, 0xfffffff8));
-		CHECK_STATUS(ddr3_tip_if_write(
-				     dev_num, ACCESS_TYPE_MULTICAST,
-				     PARAM_NOT_CARE, TRAINING_REG,
-				     (u32)(1 << 31), (u32)(1 << 31)));
-
-		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-			training_result[training_stage][if_id] = TEST_SUCCESS;
-			if (ddr3_tip_if_polling
-			    (dev_num, ACCESS_TYPE_UNICAST, if_id, 0,
-			     (u32)(1 << 31), TRAINING_REG,
-			     MAX_POLLING_ITERATIONS) != MV_OK) {
-				DEBUG_LEVELING(
-					DEBUG_LEVEL_ERROR,
-					("RL: DDR3 poll failed(1) IF %d\n",
-					 if_id));
-				training_result[training_stage][if_id] =
-					TEST_FAILED;
-
-				if (debug_mode == 0)
-					return MV_FAIL;
-			}
-		}
-
-		/* read read-leveling result */
-		CHECK_STATUS(ddr3_tip_if_read
-			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      TRAINING_REG, data_read, 1 << 30));
-		/* exit read leveling mode */
-		CHECK_STATUS(ddr3_tip_if_write
-			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      TRAINING_SW_2_REG, 0x8, 0x9));
-		CHECK_STATUS(ddr3_tip_if_write
-			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      TRAINING_SW_1_REG, 1 << 16, 1 << 16));
-
-		/* disable RL machine all Trn_CS[3:0] , [16:0] */
-
-		CHECK_STATUS(ddr3_tip_if_write
-			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      TRAINING_REG, 0, 0xf1ffff));
-
-		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-			if ((data_read[if_id] & (1 << 30)) == 0) {
-				DEBUG_LEVELING(
-					DEBUG_LEVEL_ERROR,
-					("\n_read Leveling failed for IF %d\n",
-					 if_id));
-				training_result[training_stage][if_id] =
-					TEST_FAILED;
-				if (debug_mode == 0)
-					return MV_FAIL;
-			}
-		}
-		return MV_OK;
-	}
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
-	/* NEW RL machine */
 	for (effective_cs = 0; effective_cs < NUM_OF_CS; effective_cs++)
 		for (bus_num = 0; bus_num < MAX_BUS_NUM; bus_num++)
 			for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++)
@@ -155,18 +82,18 @@ int ddr3_tip_dynamic_read_leveling(u32 dev_num, u32 freq)
 
 	for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 			training_result[training_stage][if_id] = TEST_SUCCESS;
 
 			/* save current cs enable reg val */
 			CHECK_STATUS(ddr3_tip_if_read
 				     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-				      CS_ENABLE_REG, cs_enable_reg_val,
+				      DUAL_DUNIT_CFG_REG, cs_enable_reg_val,
 				      MASK_ALL_BITS));
 			/* enable single cs */
 			CHECK_STATUS(ddr3_tip_if_write
 				     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-				      CS_ENABLE_REG, (1 << 3), (1 << 3)));
+				      DUAL_DUNIT_CFG_REG, (1 << 3), (1 << 3)));
 		}
 
 		ddr3_tip_reset_fifo_ptr(dev_num);
@@ -184,7 +111,7 @@ int ddr3_tip_dynamic_read_leveling(u32 dev_num, u32 freq)
 		/* BUS count is 0 shifted 26 */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      ODPG_DATA_CONTROL_REG, 0x3, 0x3));
+			      ODPG_DATA_CTRL_REG, 0x3, 0x3));
 		CHECK_STATUS(ddr3_tip_configure_odpg
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0,
 			      pattern_table[PATTERN_RL].num_of_phases_tx, 0,
@@ -204,17 +131,17 @@ int ddr3_tip_dynamic_read_leveling(u32 dev_num, u32 freq)
 		/* General Training Opcode register */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      ODPG_WRITE_READ_MODE_ENABLE_REG, 0,
+			      ODPG_WR_RD_MODE_ENA_REG, 0,
 			      MASK_ALL_BITS));
 
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      ODPG_TRAINING_CONTROL_REG,
+			      GENERAL_TRAINING_OPCODE_REG,
 			      (0x301b01 | effective_cs << 2), 0x3c3fef));
 
 		/* Object1 opcode register 0 & 1 */
 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 			speed_bin_index =
 				tm->interface_params[if_id].speed_bin_index;
 			cl_val =
@@ -223,13 +150,13 @@ int ddr3_tip_dynamic_read_leveling(u32 dev_num, u32 freq)
 			mask = (0xff << 9) | (0x1f << 17) | (0x3 << 25);
 			CHECK_STATUS(ddr3_tip_if_write
 				     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-				      ODPG_OBJ1_OPCODE_REG, data, mask));
+				      OPCODE_REG0_REG(1), data, mask));
 		}
 
 		/* Set iteration count to max value */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      TRAINING_OPCODE_1_REG, 0xd00, 0xd00));
+			      OPCODE_REG1_REG(1), 0xd00, 0xd00));
 
 		/*
 		 *     Phase 2: Mask config
@@ -253,11 +180,11 @@ int ddr3_tip_dynamic_read_leveling(u32 dev_num, u32 freq)
 		/* data pup rd reset enable  */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      SDRAM_CONFIGURATION_REG, 0, (1 << 30)));
+			      SDRAM_CFG_REG, 0, (1 << 30)));
 		/* data pup rd reset disable */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      SDRAM_CONFIGURATION_REG, (1 << 30), (1 << 30)));
+			      SDRAM_CFG_REG, (1 << 30), (1 << 30)));
 		/* training SW override & training RL mode */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
@@ -271,72 +198,46 @@ int ddr3_tip_dynamic_read_leveling(u32 dev_num, u32 freq)
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
 			      TRAINING_REG, (u32)(1 << 31), (u32)(1 << 31)));
 
-		/********* trigger training *******************/
-		/* Trigger, poll on status and disable ODPG */
-		CHECK_STATUS(ddr3_tip_if_write
-			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      ODPG_TRAINING_TRIGGER_REG, 0x1, 0x1));
-		CHECK_STATUS(ddr3_tip_if_write
-			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      ODPG_TRAINING_STATUS_REG, 0x1, 0x1));
+		/* trigger training */
+		mv_ddr_training_enable();
 
-		/* check for training done + results pass */
-		if (ddr3_tip_if_polling
-		    (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x2, 0x2,
-		     ODPG_TRAINING_STATUS_REG,
-		     MAX_POLLING_ITERATIONS) != MV_OK) {
-			DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
-				       ("Training Done Failed\n"));
+		/* check for training done */
+		if (mv_ddr_is_training_done(MAX_POLLING_ITERATIONS, &data) != MV_OK) {
+			DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("training done failed\n"));
 			return MV_FAIL;
 		}
+		/* check for training pass */
+		if (data != PASS)
+			DEBUG_LEVELING(DEBUG_LEVEL_INFO, ("training result failed\n"));
 
-		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-			CHECK_STATUS(ddr3_tip_if_read
-				     (dev_num, ACCESS_TYPE_UNICAST,
-				      if_id,
-				      ODPG_TRAINING_TRIGGER_REG, data_read,
-				      0x4));
-			data = data_read[if_id];
-			if (data != 0x0) {
-				DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
-					       ("Training Result Failed\n"));
-			}
-		}
+		/* disable odpg; switch back to functional mode */
+		mv_ddr_odpg_disable();
 
-		/*disable ODPG - Back to functional mode */
-		CHECK_STATUS(ddr3_tip_if_write
-			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      ODPG_ENABLE_REG, 0x1 << ODPG_DISABLE_OFFS,
-			      (0x1 << ODPG_DISABLE_OFFS)));
-		if (ddr3_tip_if_polling
-		    (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x0, 0x1,
-		     ODPG_ENABLE_REG, MAX_POLLING_ITERATIONS) != MV_OK) {
-			DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
-				       ("ODPG disable failed "));
+		if (mv_ddr_is_odpg_done(MAX_POLLING_ITERATIONS) != MV_OK) {
+			DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("odpg disable failed\n"));
 			return MV_FAIL;
 		}
-		CHECK_STATUS(ddr3_tip_if_write
-			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      ODPG_DATA_CONTROL_REG, 0, MASK_ALL_BITS));
+
+		ddr3_tip_if_write(0, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+				  ODPG_DATA_CTRL_REG, 0, MASK_ALL_BITS);
 
 		/* double loop on bus, pup */
 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 			/* check training done */
 			is_any_pup_fail = 0;
 			for (bus_num = 0;
-			     bus_num < tm->num_of_bus_per_interface;
+			     bus_num < octets_per_if_num;
 			     bus_num++) {
-				VALIDATE_ACTIVE(tm->bus_act_mask, bus_num);
+				VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_num);
 				if (ddr3_tip_if_polling
 				    (dev_num, ACCESS_TYPE_UNICAST,
 				     if_id, (1 << 25), (1 << 25),
 				     mask_results_pup_reg_map[bus_num],
 				     MAX_POLLING_ITERATIONS) != MV_OK) {
 					DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
-						       ("\n_r_l: DDR3 poll failed(2) for bus %d",
-							bus_num));
+						       ("\n_r_l: DDR3 poll failed(2) for IF %d CS %d bus %d",
+							if_id, effective_cs, bus_num));
 					is_any_pup_fail = 1;
 				} else {
 					/* read result per pup */
@@ -375,26 +276,26 @@ int ddr3_tip_dynamic_read_leveling(u32 dev_num, u32 freq)
 		/* set ODPG to functional */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      ODPG_DATA_CONTROL_REG, 0x0, MASK_ALL_BITS));
+			      ODPG_DATA_CTRL_REG, 0x0, MASK_ALL_BITS));
 
 		/*
 		 * Copy the result from the effective CS search to the
 		 * real Functional CS
 		 */
-		/*ddr3_tip_write_cs_result(dev_num, RL_PHY_REG); */
+		/*ddr3_tip_write_cs_result(dev_num, RL_PHY_REG(0); */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      ODPG_DATA_CONTROL_REG, 0x0, MASK_ALL_BITS));
+			      ODPG_DATA_CTRL_REG, 0x0, MASK_ALL_BITS));
 	}
 
 	for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
 		/* double loop on bus, pup */
 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 			for (bus_num = 0;
-			     bus_num < tm->num_of_bus_per_interface;
+			     bus_num < octets_per_if_num;
 			     bus_num++) {
-				VALIDATE_ACTIVE(tm->bus_act_mask, bus_num);
+				VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_num);
 				/* read result per pup from arry */
 				data = rl_values[effective_cs][bus_num][if_id];
 				data = (data & 0x1f) |
@@ -404,9 +305,8 @@ int ddr3_tip_dynamic_read_leveling(u32 dev_num, u32 freq)
 						   if_id,
 						   ACCESS_TYPE_UNICAST,
 						   bus_num, DDR_PHY_DATA,
-						   RL_PHY_REG +
-						   ((effective_cs ==
-						     0) ? 0x0 : 0x4), data);
+						   RL_PHY_REG(effective_cs),
+						   data);
 			}
 		}
 	}
@@ -414,11 +314,11 @@ int ddr3_tip_dynamic_read_leveling(u32 dev_num, u32 freq)
 	effective_cs = 0;
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		/* restore cs enable value */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      CS_ENABLE_REG, cs_enable_reg_val[if_id],
+			      DUAL_DUNIT_CFG_REG, cs_enable_reg_val[if_id],
 			      MASK_ALL_BITS));
 		if (odt_config != 0) {
 			CHECK_STATUS(ddr3_tip_write_additional_odt_setting
@@ -427,7 +327,7 @@ int ddr3_tip_dynamic_read_leveling(u32 dev_num, u32 freq)
 	}
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		if (training_result[training_stage][if_id] == TEST_FAILED)
 			return MV_FAIL;
 	}
@@ -441,8 +341,8 @@ int ddr3_tip_dynamic_read_leveling(u32 dev_num, u32 freq)
 int ddr3_tip_legacy_dynamic_write_leveling(u32 dev_num)
 {
 	u32 c_cs, if_id, cs_mask = 0;
-	u32 max_cs = hws_ddr3_tip_max_cs_get();
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 max_cs = ddr3_tip_max_cs_get(dev_num);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	/*
 	 * In TRAINIUNG reg (0x15b0) write 0x80000008 | cs_mask:
@@ -457,7 +357,7 @@ int ddr3_tip_legacy_dynamic_write_leveling(u32 dev_num)
 		cs_mask = cs_mask | 1 << (20 + c_cs);
 
 	for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, 0,
 			      TRAINING_REG, (0x80000008 | cs_mask),
@@ -482,8 +382,8 @@ int ddr3_tip_legacy_dynamic_write_leveling(u32 dev_num)
 int ddr3_tip_legacy_dynamic_read_leveling(u32 dev_num)
 {
 	u32 c_cs, if_id, cs_mask = 0;
-	u32 max_cs = hws_ddr3_tip_max_cs_get();
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 max_cs = ddr3_tip_max_cs_get(dev_num);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	/*
 	 * In TRAINIUNG reg (0x15b0) write 0x80000040 | cs_mask:
@@ -503,7 +403,7 @@ int ddr3_tip_legacy_dynamic_read_leveling(u32 dev_num)
 	mdelay(100);
 
 	for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		if (ddr3_tip_if_polling
 		    (dev_num, ACCESS_TYPE_UNICAST, if_id, 0,
 		     (u32)0x80000000, TRAINING_REG,
@@ -536,38 +436,39 @@ int ddr3_tip_dynamic_per_bit_read_leveling(u32 dev_num, u32 freq)
 	u32 data2_write[MAX_INTERFACE_NUM][MAX_BUS_NUM];
 	struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
 	u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		for (bus_num = 0;
-		     bus_num <= tm->num_of_bus_per_interface; bus_num++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, bus_num);
+		     bus_num <= octets_per_if_num; bus_num++) {
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_num);
 			per_bit_rl_pup_status[if_id][bus_num] = 0;
 			data2_write[if_id][bus_num] = 0;
 			/* read current value of phy register 0x3 */
 			CHECK_STATUS(ddr3_tip_bus_read
 				     (dev_num, if_id, ACCESS_TYPE_UNICAST,
 				      bus_num, DDR_PHY_DATA,
-				      READ_CENTRALIZATION_PHY_REG,
+				      CRX_PHY_REG(0),
 				      &phyreg3_arr[if_id][bus_num]));
 		}
 	}
 
 	/* NEW RL machine */
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		training_result[training_stage][if_id] = TEST_SUCCESS;
 
 		/* save current cs enable reg val */
 		CHECK_STATUS(ddr3_tip_if_read
 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      CS_ENABLE_REG, &cs_enable_reg_val[if_id],
+			      DUAL_DUNIT_CFG_REG, &cs_enable_reg_val[if_id],
 			      MASK_ALL_BITS));
 		/* enable single cs */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      CS_ENABLE_REG, (1 << 3), (1 << 3)));
+			      DUAL_DUNIT_CFG_REG, (1 << 3), (1 << 3)));
 	}
 
 	ddr3_tip_reset_fifo_ptr(dev_num);
@@ -585,7 +486,7 @@ int ddr3_tip_dynamic_per_bit_read_leveling(u32 dev_num, u32 freq)
 		/* BUS count is 0 shifted 26 */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      ODPG_DATA_CONTROL_REG, 0x3, 0x3));
+			      ODPG_DATA_CTRL_REG, 0x3, 0x3));
 		CHECK_STATUS(ddr3_tip_configure_odpg
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0,
 			      pattern_table[PATTERN_TEST].num_of_phases_tx, 0,
@@ -605,15 +506,15 @@ int ddr3_tip_dynamic_per_bit_read_leveling(u32 dev_num, u32 freq)
 		/* General Training Opcode register */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      ODPG_WRITE_READ_MODE_ENABLE_REG, 0,
+			      ODPG_WR_RD_MODE_ENA_REG, 0,
 			      MASK_ALL_BITS));
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      ODPG_TRAINING_CONTROL_REG, 0x301b01, 0x3c3fef));
+			      GENERAL_TRAINING_OPCODE_REG, 0x301b01, 0x3c3fef));
 
 		/* Object1 opcode register 0 & 1 */
 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 			speed_bin_index =
 				tm->interface_params[if_id].speed_bin_index;
 			cl_val =
@@ -622,13 +523,13 @@ int ddr3_tip_dynamic_per_bit_read_leveling(u32 dev_num, u32 freq)
 			mask = (0xff << 9) | (0x1f << 17) | (0x3 << 25);
 			CHECK_STATUS(ddr3_tip_if_write
 				     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-				      ODPG_OBJ1_OPCODE_REG, data, mask));
+				      OPCODE_REG0_REG(1), data, mask));
 		}
 
 		/* Set iteration count to max value */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      TRAINING_OPCODE_1_REG, 0xd00, 0xd00));
+			      OPCODE_REG1_REG(1), 0xd00, 0xd00));
 
 		/*
 		 *     Phase 2: Mask config
@@ -652,11 +553,11 @@ int ddr3_tip_dynamic_per_bit_read_leveling(u32 dev_num, u32 freq)
 		/* data pup rd reset enable  */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      SDRAM_CONFIGURATION_REG, 0, (1 << 30)));
+			      SDRAM_CFG_REG, 0, (1 << 30)));
 		/* data pup rd reset disable */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      SDRAM_CONFIGURATION_REG, (1 << 30), (1 << 30)));
+			      SDRAM_CFG_REG, (1 << 30), (1 << 30)));
 		/* training SW override & training RL mode */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
@@ -670,63 +571,37 @@ int ddr3_tip_dynamic_per_bit_read_leveling(u32 dev_num, u32 freq)
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
 			      TRAINING_REG, (u32)(1 << 31), (u32)(1 << 31)));
 
-		/********* trigger training *******************/
-		/* Trigger, poll on status and disable ODPG */
-		CHECK_STATUS(ddr3_tip_if_write
-			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      ODPG_TRAINING_TRIGGER_REG, 0x1, 0x1));
-		CHECK_STATUS(ddr3_tip_if_write
-			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      ODPG_TRAINING_STATUS_REG, 0x1, 0x1));
+		/* trigger training */
+		mv_ddr_training_enable();
 
-		/*check for training done + results pass */
-		if (ddr3_tip_if_polling
-		    (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x2, 0x2,
-		     ODPG_TRAINING_STATUS_REG,
-		     MAX_POLLING_ITERATIONS) != MV_OK) {
-			DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
-				       ("Training Done Failed\n"));
+		/* check for training done */
+		if (mv_ddr_is_training_done(MAX_POLLING_ITERATIONS, &data) != MV_OK) {
+			DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("training done failed\n"));
 			return MV_FAIL;
 		}
+		/* check for training pass */
+		if (data != PASS)
+			DEBUG_LEVELING(DEBUG_LEVEL_INFO, ("training result failed\n"));
 
-		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-			CHECK_STATUS(ddr3_tip_if_read
-				     (dev_num, ACCESS_TYPE_UNICAST,
-				      if_id,
-				      ODPG_TRAINING_TRIGGER_REG, data_read,
-				      0x4));
-			data = data_read[if_id];
-			if (data != 0x0) {
-				DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
-					       ("Training Result Failed\n"));
-			}
-		}
+		/* disable odpg; switch back to functional mode */
+		mv_ddr_odpg_disable();
 
-		/*disable ODPG - Back to functional mode */
-		CHECK_STATUS(ddr3_tip_if_write
-			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      ODPG_ENABLE_REG, 0x1 << ODPG_DISABLE_OFFS,
-			      (0x1 << ODPG_DISABLE_OFFS)));
-		if (ddr3_tip_if_polling
-		    (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x0, 0x1,
-		     ODPG_ENABLE_REG, MAX_POLLING_ITERATIONS) != MV_OK) {
-			DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
-				       ("ODPG disable failed "));
+		if (mv_ddr_is_odpg_done(MAX_POLLING_ITERATIONS) != MV_OK) {
+			DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("odpg disable failed\n"));
 			return MV_FAIL;
 		}
-		CHECK_STATUS(ddr3_tip_if_write
-			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      ODPG_DATA_CONTROL_REG, 0, MASK_ALL_BITS));
+
+		ddr3_tip_if_write(0, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+				  ODPG_DATA_CTRL_REG, 0, MASK_ALL_BITS);
 
 		/* double loop on bus, pup */
 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 			/* check training done */
 			for (bus_num = 0;
-			     bus_num < tm->num_of_bus_per_interface;
+			     bus_num < octets_per_if_num;
 			     bus_num++) {
-				VALIDATE_ACTIVE(tm->bus_act_mask, bus_num);
+				VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_num);
 
 				if (per_bit_rl_pup_status[if_id][bus_num]
 				    == 0) {
@@ -796,11 +671,11 @@ int ddr3_tip_dynamic_per_bit_read_leveling(u32 dev_num, u32 freq)
 			/* if there is DLL that is not checked yet */
 			for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
 			     if_id++) {
-				VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+				VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 				for (bus_num = 0;
-				     bus_num < tm->num_of_bus_per_interface;
+				     bus_num < octets_per_if_num;
 				     bus_num++) {
-					VALIDATE_ACTIVE(tm->bus_act_mask,
+					VALIDATE_BUS_ACTIVE(tm->bus_act_mask,
 							bus_num);
 					if (per_bit_rl_pup_status[if_id]
 					    [bus_num] != 1) {
@@ -812,7 +687,7 @@ int ddr3_tip_dynamic_per_bit_read_leveling(u32 dev_num, u32 freq)
 							  if_id,
 							  ACCESS_TYPE_UNICAST,
 							  bus_num, DDR_PHY_DATA,
-							  READ_CENTRALIZATION_PHY_REG,
+							  CRX_PHY_REG(0),
 							  (phyreg3_arr[if_id]
 							   [bus_num] +
 							   adll_array[curr_numb])));
@@ -829,18 +704,17 @@ int ddr3_tip_dynamic_per_bit_read_leveling(u32 dev_num, u32 freq)
 	}		/* for ( curr_numb = 0; curr_numb <3; curr_numb++) */
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-		for (bus_num = 0; bus_num < tm->num_of_bus_per_interface;
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+		for (bus_num = 0; bus_num < octets_per_if_num;
 		     bus_num++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, bus_num);
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_num);
 			if (per_bit_rl_pup_status[if_id][bus_num] == 1)
 				ddr3_tip_bus_write(dev_num,
 						   ACCESS_TYPE_UNICAST,
 						   if_id,
 						   ACCESS_TYPE_UNICAST,
 						   bus_num, DDR_PHY_DATA,
-						   RL_PHY_REG +
-						   CS_REG_VALUE(effective_cs),
+						   RL_PHY_REG(effective_cs),
 						   data2_write[if_id]
 						   [bus_num]);
 			else
@@ -882,22 +756,22 @@ int ddr3_tip_dynamic_per_bit_read_leveling(u32 dev_num, u32 freq)
 	/* set ODPG to functional */
 	CHECK_STATUS(ddr3_tip_if_write
 		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ODPG_DATA_CONTROL_REG, 0x0, MASK_ALL_BITS));
+		      ODPG_DATA_CTRL_REG, 0x0, MASK_ALL_BITS));
 	/*
 	 * Copy the result from the effective CS search to the real
 	 * Functional CS
 	 */
-	ddr3_tip_write_cs_result(dev_num, RL_PHY_REG);
+	ddr3_tip_write_cs_result(dev_num, RL_PHY_REG(0));
 	CHECK_STATUS(ddr3_tip_if_write
 		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ODPG_DATA_CONTROL_REG, 0x0, MASK_ALL_BITS));
+		      ODPG_DATA_CTRL_REG, 0x0, MASK_ALL_BITS));
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		/* restore cs enable value */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      CS_ENABLE_REG, cs_enable_reg_val[if_id],
+			      DUAL_DUNIT_CFG_REG, cs_enable_reg_val[if_id],
 			      MASK_ALL_BITS));
 		if (odt_config != 0) {
 			CHECK_STATUS(ddr3_tip_write_additional_odt_setting
@@ -906,7 +780,7 @@ int ddr3_tip_dynamic_per_bit_read_leveling(u32 dev_num, u32 freq)
 	}
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		if (training_result[training_stage][if_id] == TEST_FAILED)
 			return MV_FAIL;
 	}
@@ -919,7 +793,8 @@ int ddr3_tip_calc_cs_mask(u32 dev_num, u32 if_id, u32 effective_cs,
 {
 	u32 all_bus_cs = 0, same_bus_cs;
 	u32 bus_cnt;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	*cs_mask = same_bus_cs = CS_BIT_MASK;
 
@@ -932,8 +807,8 @@ int ddr3_tip_calc_cs_mask(u32 dev_num, u32 if_id, u32 effective_cs,
 	 * If they are they are not the same then it's mixed mode so all CS
 	 * should be configured (when configuring the MRS)
 	 */
-	for (bus_cnt = 0; bus_cnt < tm->num_of_bus_per_interface; bus_cnt++) {
-		VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
+	for (bus_cnt = 0; bus_cnt < octets_per_if_num; bus_cnt++) {
+		VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_cnt);
 
 		all_bus_cs |= tm->interface_params[if_id].
 			as_bus_params[bus_cnt].cs_bitmask;
@@ -954,9 +829,9 @@ int ddr3_tip_calc_cs_mask(u32 dev_num, u32 if_id, u32 effective_cs,
 /*
  * Dynamic write leveling
  */
-int ddr3_tip_dynamic_write_leveling(u32 dev_num)
+int ddr3_tip_dynamic_write_leveling(u32 dev_num, int phase_remove)
 {
-	u32 reg_data = 0, iter, if_id, bus_cnt;
+	u32 reg_data = 0, temp = 0, iter, if_id, bus_cnt;
 	u32 cs_enable_reg_val[MAX_INTERFACE_NUM] = { 0 };
 	u32 cs_mask[MAX_INTERFACE_NUM];
 	u32 read_data_sample_delay_vals[MAX_INTERFACE_NUM] = { 0 };
@@ -968,28 +843,36 @@ int ddr3_tip_dynamic_write_leveling(u32 dev_num)
 	u8 wl_values[NUM_OF_CS][MAX_BUS_NUM][MAX_INTERFACE_NUM];
 	u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
 	u32 cs_mask0[MAX_INTERFACE_NUM] = { 0 };
-	u32 max_cs = hws_ddr3_tip_max_cs_get();
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 max_cs = ddr3_tip_max_cs_get(dev_num);
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 
 		training_result[training_stage][if_id] = TEST_SUCCESS;
 
 		/* save Read Data Sample Delay */
 		CHECK_STATUS(ddr3_tip_if_read
 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      READ_DATA_SAMPLE_DELAY,
+			      RD_DATA_SMPL_DLYS_REG,
 			      read_data_sample_delay_vals, MASK_ALL_BITS));
 		/* save Read Data Ready Delay */
 		CHECK_STATUS(ddr3_tip_if_read
 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      READ_DATA_READY_DELAY, read_data_ready_delay_vals,
+			      RD_DATA_RDY_DLYS_REG, read_data_ready_delay_vals,
 			      MASK_ALL_BITS));
 		/* save current cs reg val */
 		CHECK_STATUS(ddr3_tip_if_read
 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      CS_ENABLE_REG, cs_enable_reg_val, MASK_ALL_BITS));
+			      DUAL_DUNIT_CFG_REG, cs_enable_reg_val, MASK_ALL_BITS));
+	}
+
+	if (ddr3_tip_dev_attr_get(dev_num, MV_ATTR_TIP_REV) < MV_TIP_REV_3) {
+		/* Enable multi-CS */
+		CHECK_STATUS(ddr3_tip_if_write
+			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
+			     DUAL_DUNIT_CFG_REG, 0, (1 << 3)));
 	}
 
 	/*
@@ -999,19 +882,19 @@ int ddr3_tip_dynamic_write_leveling(u32 dev_num)
 	/*Assert 10 refresh commands to DRAM to all CS */
 	for (iter = 0; iter < WL_ITERATION_NUM; iter++) {
 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 			CHECK_STATUS(ddr3_tip_if_write
 				     (dev_num, ACCESS_TYPE_UNICAST,
-				      if_id, SDRAM_OPERATION_REG,
+				      if_id, SDRAM_OP_REG,
 				      (u32)((~(0xf) << 8) | 0x2), 0xf1f));
 		}
 	}
 	/* check controller back to normal */
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		if (ddr3_tip_if_polling
 		    (dev_num, ACCESS_TYPE_UNICAST, if_id, 0, 0x1f,
-		     SDRAM_OPERATION_REG, MAX_POLLING_ITERATIONS) != MV_OK) {
+		     SDRAM_OP_REG, MAX_POLLING_ITERATIONS) != MV_OK) {
 			DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
 				       ("WL: DDR3 poll failed(3)"));
 		}
@@ -1020,24 +903,30 @@ int ddr3_tip_dynamic_write_leveling(u32 dev_num)
 	for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
 		/*enable write leveling to all cs  - Q off , WL n */
 		/* calculate interface cs mask */
-		CHECK_STATUS(ddr3_tip_write_mrs_cmd(dev_num, cs_mask0, MRS1_CMD,
+		CHECK_STATUS(ddr3_tip_write_mrs_cmd(dev_num, cs_mask0, MR_CMD1,
 						    0x1000, 0x1080));
 
 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 			/* cs enable is active low */
 			ddr3_tip_calc_cs_mask(dev_num, if_id, effective_cs,
 					      &cs_mask[if_id]);
 		}
 
-		/* Enable Output buffer to relevant CS - Q on , WL on */
-		CHECK_STATUS(ddr3_tip_write_mrs_cmd
-			     (dev_num, cs_mask, MRS1_CMD, 0x80, 0x1080));
+		if (ddr3_tip_dev_attr_get(dev_num, MV_ATTR_TIP_REV) >= MV_TIP_REV_3) {
+			/* Enable Output buffer to relevant CS - Q on , WL on */
+			CHECK_STATUS(ddr3_tip_write_mrs_cmd
+				     (dev_num, cs_mask, MR_CMD1, 0x80, 0x1080));
 
-		/*enable odt for relevant CS */
-		CHECK_STATUS(ddr3_tip_if_write
-			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      0x1498, (0x3 << (effective_cs * 2)), 0xf));
+			/*enable odt for relevant CS */
+			CHECK_STATUS(ddr3_tip_if_write
+				     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+				      0x1498, (0x3 << (effective_cs * 2)), 0xf));
+		} else {
+			/* FIXME: should be the same as _CPU case */
+			CHECK_STATUS(ddr3_tip_write_mrs_cmd
+				     (dev_num, cs_mask, MR_CMD1, 0xc0, 0x12c4));
+		}
 
 		/*
 		 *     Phase 2: Set training IP to write leveling mode
@@ -1045,110 +934,91 @@ int ddr3_tip_dynamic_write_leveling(u32 dev_num)
 
 		CHECK_STATUS(ddr3_tip_dynamic_write_leveling_seq(dev_num));
 
+		/* phase 3: trigger training */
+		mv_ddr_training_enable();
+
+		/* check for training done */
+		if (mv_ddr_is_training_done(MAX_POLLING_ITERATIONS, data_read) != MV_OK) {
+			DEBUG_LEVELING(DEBUG_LEVEL_ERROR, ("training done failed\n"));
+		} else { /* check for training pass */
+			reg_data = data_read[0];
+#if defined(CONFIG_ARMADA_38X) /* JIRA #1498 for 16 bit with ECC */
+			if (tm->bus_act_mask == 0xb) /* set to data to 0 to skip the check */
+				reg_data = 0;
+#endif
+			if (reg_data != PASS)
+				DEBUG_LEVELING(DEBUG_LEVEL_INFO, ("training result failed\n"));
+
+			/* check for training completion per bus */
+			for (bus_cnt = 0; bus_cnt < octets_per_if_num; bus_cnt++) {
+				VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_cnt);
+				/* training status */
+				ddr3_tip_if_read(0, ACCESS_TYPE_UNICAST, 0,
+					      mask_results_pup_reg_map[bus_cnt],
+					      data_read, MASK_ALL_BITS);
+				reg_data = data_read[0];
+				DEBUG_LEVELING(DEBUG_LEVEL_TRACE, ("WL: IF %d BUS %d reg 0x%x\n",
+								   0, bus_cnt, reg_data));
+				if ((reg_data & (1 << 25)) == 0)
+					res_values[bus_cnt] = 1;
+				ddr3_tip_if_read(0, ACCESS_TYPE_UNICAST, 0,
+					      mask_results_pup_reg_map[bus_cnt],
+					      data_read, 0xff);
+				/*
+				 * Save the read value that should be
+				 * write to PHY register
+				 */
+				wl_values[effective_cs][bus_cnt][0] = (u8)data_read[0];
+			}
+		}
+
 		/*
-		 *     Phase 3: Trigger training
+		 *     Phase 3.5: Validate result
 		 */
-
-		CHECK_STATUS(ddr3_tip_if_write
-			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      ODPG_TRAINING_TRIGGER_REG, 0x1, 0x1));
-
 		for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-
-			/* training done */
-			if (ddr3_tip_if_polling
-			    (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			     (1 << 1), (1 << 1), ODPG_TRAINING_STATUS_REG,
-			     MAX_POLLING_ITERATIONS) != MV_OK) {
-				DEBUG_LEVELING(
-					DEBUG_LEVEL_ERROR,
-					("WL: DDR3 poll (4) failed (Data: 0x%x)\n",
-					 reg_data));
-			}
-#if !defined(CONFIG_ARMADA_38X)	/*Disabled. JIRA #1498 */
-			else {
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+			for (bus_cnt = 0; bus_cnt < octets_per_if_num; bus_cnt++) {
+				VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_cnt);
+				/*
+				 * Read result control register according to subphy
+				 * "16" below is for a half-phase
+				 */
+				reg_data = wl_values[effective_cs][bus_cnt][if_id] + 16;
+				/*
+				 * Write to WL register: ADLL [4:0], Phase [8:6],
+				 * Centralization ADLL [15:10] + 0x10
+				 */
+				reg_data = (reg_data & 0x1f) |
+					   (((reg_data & 0xe0) >> 5) << 6) |
+					   (((reg_data & 0x1f) + phy_reg1_val) << 10);
+				/* Search with WL CS0 subphy reg */
+				ddr3_tip_bus_write(dev_num, ACCESS_TYPE_UNICAST, if_id,
+						   ACCESS_TYPE_UNICAST, bus_cnt,
+						   DDR_PHY_DATA, WL_PHY_REG(0), reg_data);
+				/*
+				 * Check for change in data read from DRAM.
+				 * If changed, fix the result
+				 */
 				CHECK_STATUS(ddr3_tip_if_read
-					     (dev_num, ACCESS_TYPE_UNICAST,
+					     (dev_num,
+					      ACCESS_TYPE_UNICAST,
 					      if_id,
-					      ODPG_TRAINING_TRIGGER_REG,
-					      &reg_data, (1 << 2)));
-				if (reg_data != 0) {
+					      TRAINING_WL_REG,
+					      data_read, MASK_ALL_BITS));
+				if (((data_read[if_id] & (1 << (bus_cnt + 20))) >>
+				     (bus_cnt + 20)) == 0) {
 					DEBUG_LEVELING(
 						DEBUG_LEVEL_ERROR,
-						("WL: WL failed IF %d reg_data=0x%x\n",
-						 if_id, reg_data));
-				}
-			}
-#endif
-		}
-
-		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-			/* training done */
-			if (ddr3_tip_if_polling
-			    (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			     (1 << 1), (1 << 1), ODPG_TRAINING_STATUS_REG,
-			     MAX_POLLING_ITERATIONS) != MV_OK) {
-				DEBUG_LEVELING(
-					DEBUG_LEVEL_ERROR,
-					("WL: DDR3 poll (4) failed (Data: 0x%x)\n",
-					 reg_data));
-			} else {
-#if !defined(CONFIG_ARMADA_38X)	/*Disabled. JIRA #1498 */
-				CHECK_STATUS(ddr3_tip_if_read
-					     (dev_num, ACCESS_TYPE_UNICAST,
-					      if_id,
-					      ODPG_TRAINING_STATUS_REG,
-					      data_read, (1 << 2)));
-				reg_data = data_read[if_id];
-				if (reg_data != 0) {
+						("WLValues was changed from 0x%X",
+						 wl_values[effective_cs]
+						 [bus_cnt][if_id]));
+					wl_values[effective_cs]
+					[bus_cnt][if_id] += 32;
 					DEBUG_LEVELING(
 						DEBUG_LEVEL_ERROR,
-						("WL: WL failed IF %d reg_data=0x%x\n",
-						 if_id, reg_data));
-				}
-#endif
-
-				/* check for training completion per bus */
-				for (bus_cnt = 0;
-				     bus_cnt < tm->num_of_bus_per_interface;
-				     bus_cnt++) {
-					VALIDATE_ACTIVE(tm->bus_act_mask,
-							bus_cnt);
-					/* training status */
-					CHECK_STATUS(ddr3_tip_if_read
-						     (dev_num,
-						      ACCESS_TYPE_UNICAST,
-						      if_id,
-						      mask_results_pup_reg_map
-						      [bus_cnt], data_read,
-						      (1 << 25)));
-					reg_data = data_read[if_id];
-					DEBUG_LEVELING(
-						DEBUG_LEVEL_TRACE,
-						("WL: IF %d BUS %d reg 0x%x\n",
-						 if_id, bus_cnt, reg_data));
-					if (reg_data == 0) {
-						res_values[
-							(if_id *
-							 tm->num_of_bus_per_interface)
-							+ bus_cnt] = 1;
-					}
-					CHECK_STATUS(ddr3_tip_if_read
-						     (dev_num,
-						      ACCESS_TYPE_UNICAST,
-						      if_id,
-						      mask_results_pup_reg_map
-						      [bus_cnt], data_read,
-						      0xff));
-					/*
-					 * Save the read value that should be
-					 * write to PHY register
-					 */
-					wl_values[effective_cs]
-						[bus_cnt][if_id] =
-						(u8)data_read[if_id];
+						("to 0x%X",
+						 wl_values[effective_cs]
+						 [bus_cnt][if_id]));
 				}
 			}
 		}
@@ -1160,15 +1030,21 @@ int ddr3_tip_dynamic_write_leveling(u32 dev_num)
 		/* disable DQs toggling */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-			      WR_LEVELING_DQS_PATTERN_REG, 0x0, 0x1));
+			      WL_DQS_PATTERN_REG, 0x0, 0x1));
 
 		/* Update MRS 1 (WL off) */
-		CHECK_STATUS(ddr3_tip_write_mrs_cmd(dev_num, cs_mask0, MRS1_CMD,
-						    0x1000, 0x1080));
+		if (ddr3_tip_dev_attr_get(dev_num, MV_ATTR_TIP_REV) >= MV_TIP_REV_3) {
+			CHECK_STATUS(ddr3_tip_write_mrs_cmd(dev_num, cs_mask0, MR_CMD1,
+							    0x1000, 0x1080));
+		} else {
+			/* FIXME: should be same as _CPU case */
+			CHECK_STATUS(ddr3_tip_write_mrs_cmd(dev_num, cs_mask0, MR_CMD1,
+							    0x1000, 0x12c4));
+		}
 
 		/* Update MRS 1 (return to functional mode - Q on , WL off) */
 		CHECK_STATUS(ddr3_tip_write_mrs_cmd
-			     (dev_num, cs_mask0, MRS1_CMD, 0x0, 0x1080));
+			     (dev_num, cs_mask0, MR_CMD1, 0x0, 0x1080));
 
 		/* set phy to normal mode */
 		CHECK_STATUS(ddr3_tip_if_write
@@ -1187,16 +1063,16 @@ int ddr3_tip_dynamic_write_leveling(u32 dev_num)
 
 	for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 			test_res = 0;
 			for (bus_cnt = 0;
-			     bus_cnt < tm->num_of_bus_per_interface;
+			     bus_cnt < octets_per_if_num;
 			     bus_cnt++) {
-				VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
+				VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_cnt);
 				/* check if result == pass */
 				if (res_values
 				    [(if_id *
-				      tm->num_of_bus_per_interface) +
+				      octets_per_if_num) +
 				     bus_cnt] == 0) {
 					/*
 					 * read result control register
@@ -1215,6 +1091,18 @@ int ddr3_tip_dynamic_write_leveling(u32 dev_num)
 						(((reg_data & 0xe0) >> 5) << 6) |
 						(((reg_data & 0x1f) +
 						  phy_reg1_val) << 10);
+					/*
+					 * in case phase remove should be executed
+					 * need to remove more than one phase.
+					 * this will take place only in low frequency,
+					 * where there could be more than one phase between sub-phys
+					 */
+					if (phase_remove == 1) {
+						temp = (reg_data >> WR_LVL_PH_SEL_OFFS) & WR_LVL_PH_SEL_PHASE1;
+						reg_data &= ~(WR_LVL_PH_SEL_MASK << WR_LVL_PH_SEL_OFFS);
+						reg_data |= (temp << WR_LVL_PH_SEL_OFFS);
+					}
+
 					ddr3_tip_bus_write(
 						dev_num,
 						ACCESS_TYPE_UNICAST,
@@ -1222,9 +1110,7 @@ int ddr3_tip_dynamic_write_leveling(u32 dev_num)
 						ACCESS_TYPE_UNICAST,
 						bus_cnt,
 						DDR_PHY_DATA,
-						WL_PHY_REG +
-						effective_cs *
-						CS_REGISTER_ADDR_OFFSET,
+						WL_PHY_REG(effective_cs),
 						reg_data);
 				} else {
 					test_res = 1;
@@ -1260,38 +1146,48 @@ int ddr3_tip_dynamic_write_leveling(u32 dev_num)
 	 * Copy the result from the effective CS search to the real
 	 * Functional CS
 	 */
-	/* ddr3_tip_write_cs_result(dev_num, WL_PHY_REG); */
+	/* ddr3_tip_write_cs_result(dev_num, WL_PHY_REG(0); */
 	/* restore saved values */
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		/* restore Read Data Sample Delay */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      READ_DATA_SAMPLE_DELAY,
+			      RD_DATA_SMPL_DLYS_REG,
 			      read_data_sample_delay_vals[if_id],
 			      MASK_ALL_BITS));
 
 		/* restore Read Data Ready Delay */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      READ_DATA_READY_DELAY,
+			      RD_DATA_RDY_DLYS_REG,
 			      read_data_ready_delay_vals[if_id],
 			      MASK_ALL_BITS));
 
 		/* enable multi cs */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      CS_ENABLE_REG, cs_enable_reg_val[if_id],
+			      DUAL_DUNIT_CFG_REG, cs_enable_reg_val[if_id],
 			      MASK_ALL_BITS));
 	}
 
-	/* Disable modt0 for CS0 training - need to adjust for multy CS */
-	CHECK_STATUS(ddr3_tip_if_write
-		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x1498,
-		      0x0, 0xf));
+	if (ddr3_tip_dev_attr_get(dev_num, MV_ATTR_TIP_REV) >= MV_TIP_REV_3) {
+		/* Disable modt0 for CS0 training - need to adjust for multi-CS
+		 * in case of ddr4 set 0xf else 0
+		 */
+		if (odt_config != 0) {
+			CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+						       SDRAM_ODT_CTRL_HIGH_REG, 0x0, 0xf));
+		}
+		else {
+			CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+						       SDRAM_ODT_CTRL_HIGH_REG, 0xf, 0xf));
+		}
+
+	}
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		if (training_result[training_stage][if_id] == TEST_FAILED)
 			return MV_FAIL;
 	}
@@ -1307,28 +1203,27 @@ int ddr3_tip_dynamic_write_leveling_supp(u32 dev_num)
 	int adll_offset;
 	u32 if_id, bus_id, data, data_tmp;
 	int is_if_fail = 0;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		is_if_fail = 0;
 
-		for (bus_id = 0; bus_id < GET_TOPOLOGY_NUM_OF_BUSES();
-		     bus_id++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+		for (bus_id = 0; bus_id < octets_per_if_num; bus_id++) {
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
 			wr_supp_res[if_id][bus_id].is_pup_fail = 1;
 			CHECK_STATUS(ddr3_tip_bus_read
 				     (dev_num, if_id, ACCESS_TYPE_UNICAST,
 				      bus_id, DDR_PHY_DATA,
-				      WRITE_CENTRALIZATION_PHY_REG +
-				      effective_cs * CS_REGISTER_ADDR_OFFSET,
+				      CTX_PHY_REG(effective_cs),
 				      &data));
 			DEBUG_LEVELING(
 				DEBUG_LEVEL_TRACE,
 				("WL Supp: adll_offset=0 data delay = %d\n",
 				 data));
 			if (ddr3_tip_wl_supp_align_phase_shift
-			    (dev_num, if_id, bus_id, 0, 0) == MV_OK) {
+			    (dev_num, if_id, bus_id) == MV_OK) {
 				DEBUG_LEVELING(
 					DEBUG_LEVEL_TRACE,
 					("WL Supp: IF %d bus_id %d adll_offset=0 Success !\n",
@@ -1341,14 +1236,12 @@ int ddr3_tip_dynamic_write_leveling_supp(u32 dev_num)
 			CHECK_STATUS(ddr3_tip_bus_write
 				     (dev_num, ACCESS_TYPE_UNICAST, if_id,
 				      ACCESS_TYPE_UNICAST, bus_id, DDR_PHY_DATA,
-				      WRITE_CENTRALIZATION_PHY_REG +
-				      effective_cs * CS_REGISTER_ADDR_OFFSET,
+				      CTX_PHY_REG(effective_cs),
 				      data + adll_offset));
 			CHECK_STATUS(ddr3_tip_bus_read
 				     (dev_num, if_id, ACCESS_TYPE_UNICAST,
 				      bus_id, DDR_PHY_DATA,
-				      WRITE_CENTRALIZATION_PHY_REG +
-				      effective_cs * CS_REGISTER_ADDR_OFFSET,
+				      CTX_PHY_REG(effective_cs),
 				      &data_tmp));
 			DEBUG_LEVELING(
 				DEBUG_LEVEL_TRACE,
@@ -1356,7 +1249,7 @@ int ddr3_tip_dynamic_write_leveling_supp(u32 dev_num)
 				 adll_offset, data_tmp));
 
 			if (ddr3_tip_wl_supp_align_phase_shift
-			    (dev_num, if_id, bus_id, adll_offset, 0) == MV_OK) {
+			    (dev_num, if_id, bus_id) == MV_OK) {
 				DEBUG_LEVELING(
 					DEBUG_LEVEL_TRACE,
 					("WL Supp: IF %d bus_id %d adll_offset= %d Success !\n",
@@ -1369,21 +1262,19 @@ int ddr3_tip_dynamic_write_leveling_supp(u32 dev_num)
 			CHECK_STATUS(ddr3_tip_bus_write
 				     (dev_num, ACCESS_TYPE_UNICAST, if_id,
 				      ACCESS_TYPE_UNICAST, bus_id, DDR_PHY_DATA,
-				      WRITE_CENTRALIZATION_PHY_REG +
-				      effective_cs * CS_REGISTER_ADDR_OFFSET,
+				      CTX_PHY_REG(effective_cs),
 				      data + adll_offset));
 			CHECK_STATUS(ddr3_tip_bus_read
 				     (dev_num, if_id, ACCESS_TYPE_UNICAST,
 				      bus_id, DDR_PHY_DATA,
-				      WRITE_CENTRALIZATION_PHY_REG +
-				      effective_cs * CS_REGISTER_ADDR_OFFSET,
+				      CTX_PHY_REG(effective_cs),
 				      &data_tmp));
 			DEBUG_LEVELING(
 				DEBUG_LEVEL_TRACE,
 				("WL Supp: adll_offset= %d data delay = %d\n",
 				 adll_offset, data_tmp));
 			if (ddr3_tip_wl_supp_align_phase_shift
-			    (dev_num, if_id, bus_id, adll_offset, 0) == MV_OK) {
+			    (dev_num, if_id, bus_id) == MV_OK) {
 				DEBUG_LEVELING(
 					DEBUG_LEVEL_TRACE,
 					("WL Supp: IF %d bus_id %d adll_offset= %d Success !\n",
@@ -1397,13 +1288,11 @@ int ddr3_tip_dynamic_write_leveling_supp(u32 dev_num)
 				is_if_fail = 1;
 			}
 		}
-		DEBUG_LEVELING(DEBUG_LEVEL_TRACE,
-			       ("WL Supp: IF %d bus_id %d is_pup_fail %d\n",
-				if_id, bus_id, is_if_fail));
 
 		if (is_if_fail == 1) {
 			DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
-				       ("WL Supp: IF %d failed\n", if_id));
+				       ("WL Supp: CS# %d: IF %d failed\n",
+					effective_cs, if_id));
 			training_result[training_stage][if_id] = TEST_FAILED;
 		} else {
 			training_result[training_stage][if_id] = TEST_SUCCESS;
@@ -1411,7 +1300,7 @@ int ddr3_tip_dynamic_write_leveling_supp(u32 dev_num)
 	}
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		if (training_result[training_stage][if_id] == TEST_FAILED)
 			return MV_FAIL;
 	}
@@ -1423,87 +1312,129 @@ int ddr3_tip_dynamic_write_leveling_supp(u32 dev_num)
  * Phase Shift
  */
 static int ddr3_tip_wl_supp_align_phase_shift(u32 dev_num, u32 if_id,
-					      u32 bus_id, u32 offset,
-					      u32 bus_id_delta)
+					      u32 bus_id)
 {
+	u32 original_phase;
+	u32 data, write_data;
+
 	wr_supp_res[if_id][bus_id].stage = PHASE_SHIFT;
-	if (ddr3_tip_xsb_compare_test(dev_num, if_id, bus_id,
-				      0, bus_id_delta) == MV_OK) {
-		wr_supp_res[if_id][bus_id].is_pup_fail = 0;
-		return MV_OK;
-	} else if (ddr3_tip_xsb_compare_test(dev_num, if_id, bus_id,
-					     ONE_CLOCK_ERROR_SHIFT,
-					     bus_id_delta) == MV_OK) {
-		/* 1 clock error */
-		wr_supp_res[if_id][bus_id].stage = CLOCK_SHIFT;
-		DEBUG_LEVELING(DEBUG_LEVEL_TRACE,
-			       ("Supp: 1 error clock for if %d pup %d with ofsset %d success\n",
-				if_id, bus_id, offset));
-		ddr3_tip_wl_supp_one_clk_err_shift(dev_num, if_id, bus_id, 0);
-		wr_supp_res[if_id][bus_id].is_pup_fail = 0;
-		return MV_OK;
-	} else if (ddr3_tip_xsb_compare_test(dev_num, if_id, bus_id,
-					     ALIGN_ERROR_SHIFT,
-					     bus_id_delta) == MV_OK) {
-		/* align error */
-		DEBUG_LEVELING(DEBUG_LEVEL_TRACE,
-			       ("Supp: align error for if %d pup %d with ofsset %d success\n",
-				if_id, bus_id, offset));
-		wr_supp_res[if_id][bus_id].stage = ALIGN_SHIFT;
-		ddr3_tip_wl_supp_align_err_shift(dev_num, if_id, bus_id, 0);
-		wr_supp_res[if_id][bus_id].is_pup_fail = 0;
+	if (ddr3_tip_xsb_compare_test
+	    (dev_num, if_id, bus_id, 0) == MV_OK)
 		return MV_OK;
-	} else {
-		wr_supp_res[if_id][bus_id].is_pup_fail = 1;
-		return MV_FAIL;
+
+	/* Read current phase */
+	CHECK_STATUS(ddr3_tip_bus_read
+		     (dev_num, if_id, ACCESS_TYPE_UNICAST, bus_id,
+		      DDR_PHY_DATA, WL_PHY_REG(effective_cs), &data));
+	original_phase = (data >> 6) & 0x7;
+
+	/* Set phase (0x0[6-8]) -2 */
+	if (original_phase >= 1) {
+		if (original_phase == 1)
+			write_data = data & ~0x1df;
+		else
+			write_data = (data & ~0x1c0) |
+				     ((original_phase - 2) << 6);
+		ddr3_tip_bus_write(dev_num, ACCESS_TYPE_UNICAST, if_id,
+				   ACCESS_TYPE_UNICAST, bus_id, DDR_PHY_DATA,
+				   WL_PHY_REG(effective_cs), write_data);
+		if (ddr3_tip_xsb_compare_test
+		    (dev_num, if_id, bus_id, -2) == MV_OK)
+			return MV_OK;
 	}
+
+	/* Set phase (0x0[6-8]) +2 */
+	if (original_phase <= 5) {
+		write_data = (data & ~0x1c0) |
+			     ((original_phase + 2) << 6);
+		ddr3_tip_bus_write(dev_num, ACCESS_TYPE_UNICAST, if_id,
+				   ACCESS_TYPE_UNICAST, bus_id, DDR_PHY_DATA,
+				   WL_PHY_REG(effective_cs), write_data);
+		if (ddr3_tip_xsb_compare_test
+		    (dev_num, if_id, bus_id, 2) == MV_OK)
+			return MV_OK;
+	}
+
+	/* Set phase (0x0[6-8]) +4 */
+	if (original_phase <= 3) {
+		write_data = (data & ~0x1c0) |
+			     ((original_phase + 4) << 6);
+		ddr3_tip_bus_write(dev_num, ACCESS_TYPE_UNICAST, if_id,
+				   ACCESS_TYPE_UNICAST, bus_id, DDR_PHY_DATA,
+				   WL_PHY_REG(effective_cs), write_data);
+		if (ddr3_tip_xsb_compare_test
+		    (dev_num, if_id, bus_id, 4) == MV_OK)
+			return MV_OK;
+	}
+
+	/* Set phase (0x0[6-8]) +6 */
+	if (original_phase <= 1) {
+		write_data = (data & ~0x1c0) |
+			     ((original_phase + 6) << 6);
+		ddr3_tip_bus_write(dev_num, ACCESS_TYPE_UNICAST, if_id,
+				   ACCESS_TYPE_UNICAST, bus_id, DDR_PHY_DATA,
+				   WL_PHY_REG(effective_cs), write_data);
+		if (ddr3_tip_xsb_compare_test
+		    (dev_num, if_id, bus_id, 6) == MV_OK)
+			return MV_OK;
+	}
+
+	/* Write original WL result back */
+	ddr3_tip_bus_write(dev_num, ACCESS_TYPE_UNICAST, if_id,
+			   ACCESS_TYPE_UNICAST, bus_id, DDR_PHY_DATA,
+			   WL_PHY_REG(effective_cs), data);
+	wr_supp_res[if_id][bus_id].is_pup_fail = 1;
+
+	return MV_FAIL;
 }
 
 /*
  * Compare Test
  */
 static int ddr3_tip_xsb_compare_test(u32 dev_num, u32 if_id, u32 bus_id,
-				     u32 edge_offset, u32 bus_id_delta)
+				     u32 edge_offset)
 {
-	u32 num_of_succ_byte_compare, word_in_pattern, abs_offset;
-	u32 word_offset, i;
+	u32 num_of_succ_byte_compare, word_in_pattern;
+	u32 word_offset, i, num_of_word_mult;
 	u32 read_pattern[TEST_PATTERN_LENGTH * 2];
 	struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
 	u32 pattern_test_pattern_table[8];
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+
+	/* 3 below for INTERFACE_BUS_MASK_16BIT */
+	num_of_word_mult = (tm->bus_act_mask == 3) ? 1 : 2;
 
 	for (i = 0; i < 8; i++) {
 		pattern_test_pattern_table[i] =
 			pattern_table_get_word(dev_num, PATTERN_TEST, (u8)i);
 	}
 
-	/* extern write, than read and compare */
-	CHECK_STATUS(ddr3_tip_ext_write
-		     (dev_num, if_id,
-		      (pattern_table[PATTERN_TEST].start_addr +
-		       ((SDRAM_CS_SIZE + 1) * effective_cs)), 1,
-		      pattern_test_pattern_table));
+	/* External write, read and compare */
+	CHECK_STATUS(ddr3_tip_load_pattern_to_mem(dev_num, PATTERN_TEST));
 
 	CHECK_STATUS(ddr3_tip_reset_fifo_ptr(dev_num));
 
 	CHECK_STATUS(ddr3_tip_ext_read
 		     (dev_num, if_id,
-		      (pattern_table[PATTERN_TEST].start_addr +
+		      ((pattern_table[PATTERN_TEST].start_addr << 3) +
 		       ((SDRAM_CS_SIZE + 1) * effective_cs)), 1, read_pattern));
 
 	DEBUG_LEVELING(
 		DEBUG_LEVEL_TRACE,
-		("XSB-compt: IF %d bus_id %d 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
-		 if_id, bus_id, read_pattern[0], read_pattern[1],
-		 read_pattern[2], read_pattern[3], read_pattern[4],
-		 read_pattern[5], read_pattern[6], read_pattern[7]));
+		("XSB-compt CS#%d: IF %d bus_id %d 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+		 effective_cs, if_id, bus_id,
+		 read_pattern[0], read_pattern[1],
+		 read_pattern[2], read_pattern[3],
+		 read_pattern[4], read_pattern[5],
+		 read_pattern[6], read_pattern[7]));
 
 	/* compare byte per pup */
 	num_of_succ_byte_compare = 0;
 	for (word_in_pattern = start_xsb_offset;
-	     word_in_pattern < (TEST_PATTERN_LENGTH * 2); word_in_pattern++) {
-		word_offset = word_in_pattern + edge_offset;
-		if ((word_offset > (TEST_PATTERN_LENGTH * 2 - 1)) ||
-		    (word_offset < 0))
+	     word_in_pattern < (TEST_PATTERN_LENGTH * num_of_word_mult);
+	     word_in_pattern++) {
+		word_offset = word_in_pattern;
+		if ((word_offset > (TEST_PATTERN_LENGTH * 2 - 1)))
 			continue;
 
 		if ((read_pattern[word_in_pattern] & pup_mask_table[bus_id]) ==
@@ -1512,19 +1443,20 @@ static int ddr3_tip_xsb_compare_test(u32 dev_num, u32 if_id, u32 bus_id,
 			num_of_succ_byte_compare++;
 	}
 
-	abs_offset = (edge_offset > 0) ? edge_offset : -edge_offset;
-	if (num_of_succ_byte_compare == ((TEST_PATTERN_LENGTH * 2) -
-					 abs_offset - start_xsb_offset)) {
-		DEBUG_LEVELING(
-			DEBUG_LEVEL_TRACE,
-			("XSB-compt: IF %d bus_id %d num_of_succ_byte_compare %d - Success\n",
-			 if_id, bus_id, num_of_succ_byte_compare));
+	if ((TEST_PATTERN_LENGTH * num_of_word_mult - start_xsb_offset) ==
+	    num_of_succ_byte_compare) {
+		wr_supp_res[if_id][bus_id].stage = edge_offset;
+		DEBUG_LEVELING(DEBUG_LEVEL_TRACE,
+			       ("supplementary: shift to %d for if %d pup %d success\n",
+				edge_offset, if_id, bus_id));
+		wr_supp_res[if_id][bus_id].is_pup_fail = 0;
+
 		return MV_OK;
 	} else {
 		DEBUG_LEVELING(
 			DEBUG_LEVEL_TRACE,
-			("XSB-compt: IF %d bus_id %d num_of_succ_byte_compare %d - Fail !\n",
-			 if_id, bus_id, num_of_succ_byte_compare));
+			("XSB-compt CS#%d: IF %d bus_id %d num_of_succ_byte_compare %d - Fail!\n",
+			 effective_cs, if_id, bus_id, num_of_succ_byte_compare));
 
 		DEBUG_LEVELING(
 			DEBUG_LEVEL_TRACE,
@@ -1545,116 +1477,10 @@ static int ddr3_tip_xsb_compare_test(u32 dev_num, u32 if_id, u32 bus_id,
 			 read_pattern[4], read_pattern[5],
 			 read_pattern[6], read_pattern[7]));
 
-		DEBUG_LEVELING(
-			DEBUG_LEVEL_TRACE,
-			("XSB-compt: IF %d bus_id %d num_of_succ_byte_compare %d - Fail !\n",
-			 if_id, bus_id, num_of_succ_byte_compare));
-
 		return MV_FAIL;
 	}
 }
 
-/*
- * Clock error shift - function moves the write leveling delay 1cc forward
- */
-static int ddr3_tip_wl_supp_one_clk_err_shift(u32 dev_num, u32 if_id,
-					      u32 bus_id, u32 bus_id_delta)
-{
-	int phase, adll;
-	u32 data;
-	DEBUG_LEVELING(DEBUG_LEVEL_TRACE, ("One_clk_err_shift\n"));
-
-	CHECK_STATUS(ddr3_tip_bus_read
-		     (dev_num, if_id, ACCESS_TYPE_UNICAST, bus_id,
-		      DDR_PHY_DATA, WL_PHY_REG, &data));
-	phase = ((data >> 6) & 0x7);
-	adll = data & 0x1f;
-	DEBUG_LEVELING(DEBUG_LEVEL_TRACE,
-		       ("One_clk_err_shift: IF %d bus_id %d phase %d adll %d\n",
-			if_id, bus_id, phase, adll));
-
-	if ((phase == 0) || (phase == 1)) {
-		CHECK_STATUS(ddr3_tip_bus_read_modify_write
-			     (dev_num, ACCESS_TYPE_UNICAST, if_id, bus_id,
-			      DDR_PHY_DATA, 0, (phase + 2), 0x1f));
-	} else if (phase == 2) {
-		if (adll < 6) {
-			data = (3 << 6) + (0x1f);
-			CHECK_STATUS(ddr3_tip_bus_read_modify_write
-				     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-				      bus_id, DDR_PHY_DATA, 0, data,
-				      (0x7 << 6 | 0x1f)));
-			data = 0x2f;
-			CHECK_STATUS(ddr3_tip_bus_read_modify_write
-				     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-				      bus_id, DDR_PHY_DATA, 1, data, 0x3f));
-		}
-	} else {
-		/* phase 3 */
-		return MV_FAIL;
-	}
-
-	return MV_OK;
-}
-
-/*
- * Align error shift
- */
-static int ddr3_tip_wl_supp_align_err_shift(u32 dev_num, u32 if_id,
-					    u32 bus_id, u32 bus_id_delta)
-{
-	int phase, adll;
-	u32 data;
-
-	/* Shift WL result 1 phase back */
-	CHECK_STATUS(ddr3_tip_bus_read(dev_num, if_id, ACCESS_TYPE_UNICAST,
-				       bus_id, DDR_PHY_DATA, WL_PHY_REG,
-				       &data));
-	phase = ((data >> 6) & 0x7);
-	adll = data & 0x1f;
-	DEBUG_LEVELING(
-		DEBUG_LEVEL_TRACE,
-		("Wl_supp_align_err_shift: IF %d bus_id %d phase %d adll %d\n",
-		 if_id, bus_id, phase, adll));
-
-	if (phase < 2) {
-		if (adll > 0x1a) {
-			if (phase == 0)
-				return MV_FAIL;
-
-			if (phase == 1) {
-				data = 0;
-				CHECK_STATUS(ddr3_tip_bus_read_modify_write
-					     (dev_num, ACCESS_TYPE_UNICAST,
-					      if_id, bus_id, DDR_PHY_DATA,
-					      0, data, (0x7 << 6 | 0x1f)));
-				data = 0xf;
-				CHECK_STATUS(ddr3_tip_bus_read_modify_write
-					     (dev_num, ACCESS_TYPE_UNICAST,
-					      if_id, bus_id, DDR_PHY_DATA,
-					      1, data, 0x1f));
-				return MV_OK;
-			}
-		} else {
-			return MV_FAIL;
-		}
-	} else if ((phase == 2) || (phase == 3)) {
-		phase = phase - 2;
-		data = (phase << 6) + (adll & 0x1f);
-		CHECK_STATUS(ddr3_tip_bus_read_modify_write
-			     (dev_num, ACCESS_TYPE_UNICAST, if_id, bus_id,
-			      DDR_PHY_DATA, 0, data, (0x7 << 6 | 0x1f)));
-		return MV_OK;
-	} else {
-		DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
-			       ("Wl_supp_align_err_shift: unexpected phase\n"));
-
-		return MV_FAIL;
-	}
-
-	return MV_OK;
-}
-
 /*
  * Dynamic write leveling sequence
  */
@@ -1663,32 +1489,33 @@ static int ddr3_tip_dynamic_write_leveling_seq(u32 dev_num)
 	u32 bus_id, dq_id;
 	u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
 	u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	CHECK_STATUS(ddr3_tip_if_write
 		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
 		      TRAINING_SW_2_REG, 0x1, 0x5));
 	CHECK_STATUS(ddr3_tip_if_write
 		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      TRAINING_WRITE_LEVELING_REG, 0x50, 0xff));
+		      TRAINING_WL_REG, 0x50, 0xff));
 	CHECK_STATUS(ddr3_tip_if_write
 		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      TRAINING_WRITE_LEVELING_REG, 0x5c, 0xff));
+		      TRAINING_WL_REG, 0x5c, 0xff));
 	CHECK_STATUS(ddr3_tip_if_write
 		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ODPG_TRAINING_CONTROL_REG, 0x381b82, 0x3c3faf));
+		      GENERAL_TRAINING_OPCODE_REG, 0x381b82, 0x3c3faf));
 	CHECK_STATUS(ddr3_tip_if_write
 		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ODPG_OBJ1_OPCODE_REG, (0x3 << 25), (0x3ffff << 9)));
+		      OPCODE_REG0_REG(1), (0x3 << 25), (0x3ffff << 9)));
 	CHECK_STATUS(ddr3_tip_if_write
 		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ODPG_OBJ1_ITER_CNT_REG, 0x80, 0xffff));
+		      OPCODE_REG1_REG(1), 0x80, 0xffff));
 	CHECK_STATUS(ddr3_tip_if_write
 		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ODPG_WRITE_LEVELING_DONE_CNTR_REG, 0x14, 0xff));
+		      WL_DONE_CNTR_REF_REG, 0x14, 0xff));
 	CHECK_STATUS(ddr3_tip_if_write
 		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      TRAINING_WRITE_LEVELING_REG, 0xff5c, 0xffff));
+		      TRAINING_WL_REG, 0xff5c, 0xffff));
 
 	/* mask PBS */
 	for (dq_id = 0; dq_id < MAX_DQ_NUM; dq_id++) {
@@ -1699,7 +1526,7 @@ static int ddr3_tip_dynamic_write_leveling_seq(u32 dev_num)
 	}
 
 	/* Mask all results */
-	for (bus_id = 0; bus_id < tm->num_of_bus_per_interface; bus_id++) {
+	for (bus_id = 0; bus_id < octets_per_if_num; bus_id++) {
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
 			      mask_results_pup_reg_map[bus_id], 0x1 << 24,
@@ -1707,8 +1534,8 @@ static int ddr3_tip_dynamic_write_leveling_seq(u32 dev_num)
 	}
 
 	/* Unmask only wanted */
-	for (bus_id = 0; bus_id < tm->num_of_bus_per_interface; bus_id++) {
-		VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+	for (bus_id = 0; bus_id < octets_per_if_num; bus_id++) {
+		VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
 			      mask_results_pup_reg_map[bus_id], 0, 0x1 << 24));
@@ -1716,7 +1543,7 @@ static int ddr3_tip_dynamic_write_leveling_seq(u32 dev_num)
 
 	CHECK_STATUS(ddr3_tip_if_write
 		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      WR_LEVELING_DQS_PATTERN_REG, 0x1, 0x1));
+		      WL_DQS_PATTERN_REG, 0x1, 0x1));
 
 	return MV_OK;
 }
@@ -1729,7 +1556,8 @@ static int ddr3_tip_dynamic_read_leveling_seq(u32 dev_num)
 	u32 bus_id, dq_id;
 	u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
 	u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	/* mask PBS */
 	for (dq_id = 0; dq_id < MAX_DQ_NUM; dq_id++) {
@@ -1740,7 +1568,7 @@ static int ddr3_tip_dynamic_read_leveling_seq(u32 dev_num)
 	}
 
 	/* Mask all results */
-	for (bus_id = 0; bus_id < tm->num_of_bus_per_interface; bus_id++) {
+	for (bus_id = 0; bus_id < octets_per_if_num; bus_id++) {
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
 			      mask_results_pup_reg_map[bus_id], 0x1 << 24,
@@ -1748,8 +1576,8 @@ static int ddr3_tip_dynamic_read_leveling_seq(u32 dev_num)
 	}
 
 	/* Unmask only wanted */
-	for (bus_id = 0; bus_id < tm->num_of_bus_per_interface; bus_id++) {
-		VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+	for (bus_id = 0; bus_id < octets_per_if_num; bus_id++) {
+		VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
 			      mask_results_pup_reg_map[bus_id], 0, 0x1 << 24));
@@ -1766,7 +1594,8 @@ static int ddr3_tip_dynamic_per_bit_read_leveling_seq(u32 dev_num)
 	u32 bus_id, dq_id;
 	u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
 	u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	/* mask PBS */
 	for (dq_id = 0; dq_id < MAX_DQ_NUM; dq_id++) {
@@ -1777,7 +1606,7 @@ static int ddr3_tip_dynamic_per_bit_read_leveling_seq(u32 dev_num)
 	}
 
 	/* Mask all results */
-	for (bus_id = 0; bus_id < tm->num_of_bus_per_interface; bus_id++) {
+	for (bus_id = 0; bus_id < octets_per_if_num; bus_id++) {
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
 			      mask_results_pup_reg_map[bus_id], 0x1 << 24,
@@ -1786,7 +1615,7 @@ static int ddr3_tip_dynamic_per_bit_read_leveling_seq(u32 dev_num)
 
 	/* Unmask only wanted */
 	for (dq_id = 0; dq_id < MAX_DQ_NUM; dq_id++) {
-		VALIDATE_ACTIVE(tm->bus_act_mask, dq_id / 8);
+		VALIDATE_BUS_ACTIVE(tm->bus_act_mask, dq_id / 8);
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
 			      mask_results_dq_reg_map[dq_id], 0x0 << 24,
@@ -1802,16 +1631,17 @@ static int ddr3_tip_dynamic_per_bit_read_leveling_seq(u32 dev_num)
 int ddr3_tip_print_wl_supp_result(u32 dev_num)
 {
 	u32 bus_id = 0, if_id = 0;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	DEBUG_LEVELING(DEBUG_LEVEL_INFO,
 		       ("I/F0 PUP0 Result[0 - success, 1-fail] ...\n"));
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-		for (bus_id = 0; bus_id < tm->num_of_bus_per_interface;
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+		for (bus_id = 0; bus_id < octets_per_if_num;
 		     bus_id++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
 			DEBUG_LEVELING(DEBUG_LEVEL_INFO,
 				       ("%d ,", wr_supp_res[if_id]
 					[bus_id].is_pup_fail));
@@ -1822,10 +1652,10 @@ int ddr3_tip_print_wl_supp_result(u32 dev_num)
 		("I/F0 PUP0 Stage[0-phase_shift, 1-clock_shift, 2-align_shift] ...\n"));
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-		for (bus_id = 0; bus_id < tm->num_of_bus_per_interface;
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+		for (bus_id = 0; bus_id < octets_per_if_num;
 		     bus_id++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_id);
 			DEBUG_LEVELING(DEBUG_LEVEL_INFO,
 				       ("%d ,", wr_supp_res[if_id]
 					[bus_id].stage));
@@ -1834,3 +1664,324 @@ int ddr3_tip_print_wl_supp_result(u32 dev_num)
 
 	return MV_OK;
 }
+
+#define RD_FIFO_PTR_LOW_STAT_INDIR_ADDR		0x9a
+#define RD_FIFO_PTR_HIGH_STAT_INDIR_ADDR	0x9b
+/* position of falling dqs edge in fifo; walking 1 */
+#define RD_FIFO_DQS_FALL_EDGE_POS_0		0x1
+#define RD_FIFO_DQS_FALL_EDGE_POS_1		0x2
+#define RD_FIFO_DQS_FALL_EDGE_POS_2		0x4
+#define RD_FIFO_DQS_FALL_EDGE_POS_3		0x8
+#define RD_FIFO_DQS_FALL_EDGE_POS_4		0x10 /* lock */
+/* position of rising dqs edge in fifo; walking 0 */
+#define RD_FIFO_DQS_RISE_EDGE_POS_0		0x1fff
+#define RD_FIFO_DQS_RISE_EDGE_POS_1		0x3ffe
+#define RD_FIFO_DQS_RISE_EDGE_POS_2		0x3ffd
+#define RD_FIFO_DQS_RISE_EDGE_POS_3		0x3ffb
+#define RD_FIFO_DQS_RISE_EDGE_POS_4		0x3ff7 /* lock */
+#define TEST_ADDR		0x8
+#define TAPS_PER_UI		32
+#define UI_PER_RD_SAMPLE	4
+#define TAPS_PER_RD_SAMPLE	((UI_PER_RD_SAMPLE) * (TAPS_PER_UI))
+#define MAX_RD_SAMPLES		32
+#define MAX_RL_VALUE		((MAX_RD_SAMPLES) * (TAPS_PER_RD_SAMPLE))
+#define RD_FIFO_DLY		8
+#define STEP_SIZE		64
+#define RL_JITTER_WIDTH_LMT	20
+#define ADLL_TAPS_IN_CYCLE	64
+
+enum rl_dqs_burst_state {
+	RL_AHEAD = 0,
+	RL_INSIDE,
+	RL_BEHIND
+};
+int mv_ddr_rl_dqs_burst(u32 dev_num, u32 if_id, u32 freq)
+{
+	enum rl_dqs_burst_state rl_state[NUM_OF_CS][MAX_BUS_NUM][MAX_INTERFACE_NUM] = { { {0} } };
+	enum hws_ddr_phy subphy_type = DDR_PHY_DATA;
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+	int cl_val = tm->interface_params[0].cas_l;
+	int rl_adll_val, rl_phase_val, sdr_cycle_incr, rd_sample, rd_ready;
+	int final_rd_sample, final_rd_ready;
+	int i, subphy_id, step;
+	int pass_lock_num = 0;
+	int init_pass_lock_num;
+	int phase_delta;
+	int min_phase, max_phase;
+	u32 max_cs = ddr3_tip_max_cs_get(dev_num);
+	u32 rl_values[NUM_OF_CS][MAX_BUS_NUM][MAX_INTERFACE_NUM] = { { {0} } };
+	u32 rl_min_values[NUM_OF_CS][MAX_BUS_NUM][MAX_INTERFACE_NUM] = { { {0} } };
+	u32 rl_max_values[NUM_OF_CS][MAX_BUS_NUM][MAX_INTERFACE_NUM] = { { {0} } };
+	u32 rl_val, rl_min_val[NUM_OF_CS], rl_max_val[NUM_OF_CS];
+	u32 reg_val_low, reg_val_high;
+	u32 reg_val,  reg_mask;
+	uintptr_t test_addr = TEST_ADDR;
+
+	/* initialization */
+	if (ddr3_if_ecc_enabled()) {
+		ddr3_tip_if_read(dev_num, ACCESS_TYPE_UNICAST, if_id, TRAINING_SW_2_REG,
+				 &reg_val, MASK_ALL_BITS);
+		reg_mask = (TRAINING_ECC_MUX_MASK << TRAINING_ECC_MUX_OFFS) |
+			   (TRAINING_SW_OVRD_MASK << TRAINING_SW_OVRD_OFFS);
+		reg_val &= ~reg_mask;
+		reg_val |= (TRAINING_ECC_MUX_DIS << TRAINING_ECC_MUX_OFFS) |
+			   (TRAINING_SW_OVRD_ENA << TRAINING_SW_OVRD_OFFS);
+		ddr3_tip_if_write(0, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, TRAINING_SW_2_REG,
+				  reg_val, MASK_ALL_BITS);
+		ddr3_tip_if_read(dev_num, ACCESS_TYPE_UNICAST, if_id, TRAINING_REG,
+				 &reg_val, MASK_ALL_BITS);
+		reg_mask = (TRN_START_MASK << TRN_START_OFFS);
+		reg_val &= ~reg_mask;
+		reg_val |= TRN_START_ENA << TRN_START_OFFS;
+		ddr3_tip_if_write(0, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, TRAINING_REG,
+				  reg_val, MASK_ALL_BITS);
+	}
+
+	for (effective_cs = 0; effective_cs < max_cs; effective_cs++)
+		for (subphy_id = 0; subphy_id < MAX_BUS_NUM; subphy_id++)
+			for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++)
+				if (IS_BUS_ACTIVE(tm->bus_act_mask, subphy_id) == 0)
+					pass_lock_num++; /* increment on inactive subphys */
+
+	init_pass_lock_num = pass_lock_num / max_cs;
+	for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
+		for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+			training_result[training_stage][if_id] = TEST_SUCCESS;
+		}
+	}
+
+	/* search for dqs edges per subphy */
+	if_id = 0;
+	for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
+		pass_lock_num = init_pass_lock_num;
+		ddr3_tip_if_write(0, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_DATA_CTRL_REG,
+				  effective_cs << ODPG_DATA_CS_OFFS,
+				  ODPG_DATA_CS_MASK << ODPG_DATA_CS_OFFS);
+		rl_min_val[effective_cs] = MAX_RL_VALUE;
+		rl_max_val[effective_cs] = 0;
+		step = STEP_SIZE;
+		for (i = 0; i < MAX_RL_VALUE; i += step) {
+			rl_val = 0;
+			sdr_cycle_incr = i / TAPS_PER_RD_SAMPLE; /* sdr cycle increment */
+			rd_sample = cl_val + 2 * sdr_cycle_incr;
+			/* fifo out to in delay in search is constant */
+			rd_ready = rd_sample + RD_FIFO_DLY;
+
+			ddr3_tip_if_write(0, ACCESS_TYPE_UNICAST, 0, RD_DATA_SMPL_DLYS_REG,
+					  rd_sample << RD_SMPL_DLY_CS_OFFS(effective_cs),
+					  RD_SMPL_DLY_CS_MASK << RD_SMPL_DLY_CS_OFFS(effective_cs));
+			ddr3_tip_if_write(0, ACCESS_TYPE_UNICAST, 0, RD_DATA_RDY_DLYS_REG,
+					  rd_ready << RD_RDY_DLY_CS_OFFS(effective_cs),
+					  RD_RDY_DLY_CS_MASK << RD_RDY_DLY_CS_OFFS(effective_cs));
+
+			/* one sdr (single data rate) cycle incremented on every four phases of ddr clock */
+			sdr_cycle_incr = i % TAPS_PER_RD_SAMPLE;
+			rl_adll_val = sdr_cycle_incr % MAX_RD_SAMPLES;
+			rl_phase_val = sdr_cycle_incr / MAX_RD_SAMPLES;
+			rl_val = ((rl_adll_val & RL_REF_DLY_MASK) << RL_REF_DLY_OFFS) |
+				 ((rl_phase_val & RL_PH_SEL_MASK) << RL_PH_SEL_OFFS);
+
+			/* write to all subphys (even to not connected or locked) */
+			ddr3_tip_bus_write(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST,
+					   0, DDR_PHY_DATA, RL_PHY_REG(effective_cs), rl_val);
+
+			/* reset read fifo assertion */
+			ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST, if_id, SDRAM_CFG_REG,
+					  DATA_PUP_RD_RESET_ENA << DATA_PUP_RD_RESET_OFFS,
+					  DATA_PUP_RD_RESET_MASK << DATA_PUP_RD_RESET_OFFS);
+
+			/* reset read fifo deassertion */
+			ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST, if_id, SDRAM_CFG_REG,
+					  DATA_PUP_RD_RESET_DIS << DATA_PUP_RD_RESET_OFFS,
+					  DATA_PUP_RD_RESET_MASK << DATA_PUP_RD_RESET_OFFS);
+
+			/* perform one read burst */
+			if (MV_DDR_IS_64BIT_DRAM_MODE(tm->bus_act_mask))
+				readq(test_addr);
+			else
+				readl(test_addr);
+
+			/* progress read ptr; decide on rl state per byte */
+			for (subphy_id = 0; subphy_id < MAX_BUS_NUM; subphy_id++) {
+				if (rl_state[effective_cs][subphy_id][if_id] == RL_BEHIND)
+					continue; /* skip locked subphys */
+				ddr3_tip_bus_read(dev_num, if_id, ACCESS_TYPE_UNICAST, subphy_id, DDR_PHY_DATA,
+						  RD_FIFO_PTR_LOW_STAT_INDIR_ADDR, &reg_val_low);
+				ddr3_tip_bus_read(dev_num, if_id, ACCESS_TYPE_UNICAST, subphy_id, DDR_PHY_DATA,
+						  RD_FIFO_PTR_HIGH_STAT_INDIR_ADDR, &reg_val_high);
+				DEBUG_LEVELING(DEBUG_LEVEL_TRACE,
+					       ("%s: cs %d, step %d, subphy %d, state %d, low 0x%04x, high 0x%04x; move to ",
+						__func__, effective_cs, i, subphy_id,
+						rl_state[effective_cs][subphy_id][if_id],
+						reg_val_low, reg_val_high));
+
+				switch (rl_state[effective_cs][subphy_id][if_id]) {
+				case RL_AHEAD:
+					/* improve search resolution getting closer to the window */
+					if (reg_val_low == RD_FIFO_DQS_FALL_EDGE_POS_4 &&
+					    reg_val_high == RD_FIFO_DQS_RISE_EDGE_POS_4) {
+						rl_state[effective_cs][subphy_id][if_id] = RL_INSIDE;
+						rl_values[effective_cs][subphy_id][if_id] = i;
+						rl_min_values[effective_cs][subphy_id][if_id] = i;
+						DEBUG_LEVELING(DEBUG_LEVEL_TRACE,
+							       ("new state %d\n",
+								rl_state[effective_cs][subphy_id][if_id]));
+					} else if (reg_val_low == RD_FIFO_DQS_FALL_EDGE_POS_3 &&
+						   reg_val_high == RD_FIFO_DQS_RISE_EDGE_POS_3) {
+						step = (step < 2) ? step : 2;
+					} else if (reg_val_low == RD_FIFO_DQS_FALL_EDGE_POS_2 &&
+						   reg_val_high == RD_FIFO_DQS_RISE_EDGE_POS_2) {
+						step = (step < 16) ? step : 16;
+					} else if (reg_val_low == RD_FIFO_DQS_FALL_EDGE_POS_1 &&
+						   reg_val_high == RD_FIFO_DQS_RISE_EDGE_POS_1) {
+						step = (step < 32) ? step : 32;
+					} else if (reg_val_low == RD_FIFO_DQS_FALL_EDGE_POS_0 &&
+						   reg_val_high == RD_FIFO_DQS_RISE_EDGE_POS_0) {
+						step = (step < 64) ? step : 64;
+					} else {
+						/* otherwise, step is unchanged */
+					}
+					break;
+				case RL_INSIDE:
+					if (reg_val_low == RD_FIFO_DQS_FALL_EDGE_POS_4 &&
+					    reg_val_high == RD_FIFO_DQS_RISE_EDGE_POS_4) {
+						rl_max_values[effective_cs][subphy_id][if_id] = i;
+						if ((rl_max_values[effective_cs][subphy_id][if_id] -
+						     rl_min_values[effective_cs][subphy_id][if_id]) >
+						    ADLL_TAPS_IN_CYCLE) {
+							rl_state[effective_cs][subphy_id][if_id] = RL_BEHIND;
+							rl_values[effective_cs][subphy_id][if_id] =
+								(i + rl_values[effective_cs][subphy_id][if_id]) / 2;
+							pass_lock_num++;
+							DEBUG_LEVELING(DEBUG_LEVEL_TRACE,
+								       ("new lock %d\n", pass_lock_num));
+							if (rl_min_val[effective_cs] >
+							    rl_values[effective_cs][subphy_id][if_id])
+								rl_min_val[effective_cs] =
+									rl_values[effective_cs][subphy_id][if_id];
+							if (rl_max_val[effective_cs] <
+							    rl_values[effective_cs][subphy_id][if_id])
+								rl_max_val[effective_cs] =
+									rl_values[effective_cs][subphy_id][if_id];
+							step = 2;
+						}
+					}
+					if (reg_val_low != RD_FIFO_DQS_FALL_EDGE_POS_4 ||
+					    reg_val_high != RD_FIFO_DQS_RISE_EDGE_POS_4) {
+						if ((i - rl_values[effective_cs][subphy_id][if_id]) <
+						    RL_JITTER_WIDTH_LMT) {
+							/* inside the jitter; not valid segment */
+							rl_state[effective_cs][subphy_id][if_id] = RL_AHEAD;
+							DEBUG_LEVELING(DEBUG_LEVEL_TRACE,
+								       ("new state %d; jitter on mask\n",
+									rl_state[effective_cs][subphy_id][if_id]));
+						} else { /* finished valid segment */
+							rl_state[effective_cs][subphy_id][if_id] = RL_BEHIND;
+							rl_values[effective_cs][subphy_id][if_id] =
+								(i + rl_values[effective_cs][subphy_id][if_id]) / 2;
+							DEBUG_LEVELING(DEBUG_LEVEL_TRACE,
+								       ("new state %d, solution %d\n",
+									rl_state[effective_cs][subphy_id][if_id],
+									rl_values[effective_cs][subphy_id][if_id]));
+							pass_lock_num++;
+							DEBUG_LEVELING(DEBUG_LEVEL_TRACE,
+								       ("new lock %d\n", pass_lock_num));
+							if (rl_min_val[effective_cs] >
+							    rl_values[effective_cs][subphy_id][if_id])
+								rl_min_val[effective_cs] =
+									rl_values[effective_cs][subphy_id][if_id];
+							if (rl_max_val[effective_cs] <
+							    rl_values[effective_cs][subphy_id][if_id])
+								rl_max_val[effective_cs] =
+									rl_values[effective_cs][subphy_id][if_id];
+							step = 2;
+						}
+					}
+					break;
+				case RL_BEHIND: /* do nothing */
+					break;
+				}
+				DEBUG_LEVELING(DEBUG_LEVEL_TRACE, ("\n"));
+			}
+			DEBUG_LEVELING(DEBUG_LEVEL_TRACE, ("pass_lock_num %d\n", pass_lock_num));
+			/* exit condition */
+			if (pass_lock_num == MAX_BUS_NUM)
+				break;
+		} /* for-loop on i */
+
+		if (pass_lock_num != MAX_BUS_NUM) {
+			DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
+				       ("%s: cs %d, pass_lock_num %d, max_bus_num %d, init_pass_lock_num %d\n",
+				       __func__, effective_cs, pass_lock_num, MAX_BUS_NUM, init_pass_lock_num));
+			for (subphy_id = 0; subphy_id < MAX_BUS_NUM; subphy_id++) {
+				VALIDATE_BUS_ACTIVE(tm->bus_act_mask, subphy_id);
+				DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
+					       ("%s: subphy %d %s\n",
+						__func__, subphy_id,
+						(rl_state[effective_cs][subphy_id][if_id] == RL_BEHIND) ?
+						"locked" : "not locked"));
+			}
+		}
+	} /* for-loop on effective_cs */
+
+	/* post-processing read leveling results */
+	if_id = 0;
+	for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
+		phase_delta = 0;
+		i = rl_min_val[effective_cs];
+		sdr_cycle_incr = i / TAPS_PER_RD_SAMPLE; /* sdr cycle increment */
+		rd_sample = cl_val + 2 * sdr_cycle_incr;
+		rd_ready = rd_sample + RD_FIFO_DLY;
+		min_phase = (rl_min_val[effective_cs] - (sdr_cycle_incr * TAPS_PER_RD_SAMPLE)) % MAX_RD_SAMPLES;
+		max_phase = (rl_max_val[effective_cs] - (sdr_cycle_incr * TAPS_PER_RD_SAMPLE)) % MAX_RD_SAMPLES;
+		final_rd_sample = rd_sample;
+		final_rd_ready = rd_ready;
+
+		ddr3_tip_if_write(0, ACCESS_TYPE_UNICAST, 0, RD_DATA_SMPL_DLYS_REG,
+				  rd_sample << RD_SMPL_DLY_CS_OFFS(effective_cs),
+				  RD_SMPL_DLY_CS_MASK << RD_SMPL_DLY_CS_OFFS(effective_cs));
+		ddr3_tip_if_write(0, ACCESS_TYPE_UNICAST, 0, RD_DATA_RDY_DLYS_REG,
+				  rd_ready << RD_RDY_DLY_CS_OFFS(effective_cs),
+				  RD_RDY_DLY_CS_MASK << RD_RDY_DLY_CS_OFFS(effective_cs));
+		DEBUG_LEVELING(DEBUG_LEVEL_INFO,
+			       ("%s: cs %d, min phase %d, max phase %d, read sample %d\n",
+				__func__, effective_cs, min_phase, max_phase, rd_sample));
+
+		for (subphy_id = 0; subphy_id < MAX_BUS_NUM; subphy_id++) {
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, subphy_id);
+			/* reduce sdr cycle per cs; extract rl adll and phase values */
+			i = rl_values[effective_cs][subphy_id][if_id] - (sdr_cycle_incr * TAPS_PER_RD_SAMPLE);
+			rl_adll_val = i % MAX_RD_SAMPLES;
+			rl_phase_val = i / MAX_RD_SAMPLES;
+			rl_phase_val -= phase_delta;
+			DEBUG_LEVELING(DEBUG_LEVEL_INFO,
+				       ("%s: final results: cs %d, subphy %d, read sample %d read ready %d, rl_phase_val %d, rl_adll_val %d\n",
+					__func__, effective_cs, subphy_id, final_rd_sample,
+					final_rd_ready, rl_phase_val, rl_adll_val));
+
+			rl_val = ((rl_adll_val & RL_REF_DLY_MASK) << RL_REF_DLY_OFFS) |
+				 ((rl_phase_val & RL_PH_SEL_MASK) << RL_PH_SEL_OFFS);
+			ddr3_tip_bus_write(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_UNICAST,
+					   subphy_id, subphy_type, RL_PHY_REG(effective_cs), rl_val);
+		}
+	} /* for-loop on effective cs */
+
+	for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+		if (odt_config != 0)
+			CHECK_STATUS(ddr3_tip_write_additional_odt_setting(dev_num, if_id));
+	}
+
+	/* reset read fifo assertion */
+	ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST, if_id, SDRAM_CFG_REG,
+			  DATA_PUP_RD_RESET_ENA << DATA_PUP_RD_RESET_OFFS,
+			  DATA_PUP_RD_RESET_MASK << DATA_PUP_RD_RESET_OFFS);
+
+	/* reset read fifo deassertion */
+	ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST, if_id, SDRAM_CFG_REG,
+			  DATA_PUP_RD_RESET_DIS << DATA_PUP_RD_RESET_OFFS,
+			  DATA_PUP_RD_RESET_MASK << DATA_PUP_RD_RESET_OFFS);
+
+	return MV_OK;
+}
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_leveling.h b/drivers/ddr/marvell/a38x/ddr3_training_leveling.h
index f2b4177082c4..b6ebe731a1f7 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training_leveling.h
+++ b/drivers/ddr/marvell/a38x/ddr3_training_leveling.h
@@ -12,6 +12,6 @@
 int ddr3_tip_print_wl_supp_result(u32 dev_num);
 int ddr3_tip_calc_cs_mask(u32 dev_num, u32 if_id, u32 effective_cs,
 			  u32 *cs_mask);
-u32 hws_ddr3_tip_max_cs_get(void);
+u32 ddr3_tip_max_cs_get(u32 dev_num);
 
 #endif /* _DDR3_TRAINING_LEVELING_H_ */
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_pbs.c b/drivers/ddr/marvell/a38x/ddr3_training_pbs.c
index 2b4a58fb9fcc..9f54d96a1eb9 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training_pbs.c
+++ b/drivers/ddr/marvell/a38x/ddr3_training_pbs.c
@@ -4,12 +4,6 @@
  * SPDX-License-Identifier:	GPL-2.0
  */
 
-#include <common.h>
-#include <spl.h>
-#include <asm/io.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/soc.h>
-
 #include "ddr3_init.h"
 
 #define TYPICAL_PBS_VALUE	12
@@ -24,7 +18,7 @@ u8 max_pbs_per_pup[MAX_INTERFACE_NUM][MAX_BUS_NUM];
 u8 min_pbs_per_pup[MAX_INTERFACE_NUM][MAX_BUS_NUM];
 u8 max_adll_per_pup[MAX_INTERFACE_NUM][MAX_BUS_NUM];
 u8 min_adll_per_pup[MAX_INTERFACE_NUM][MAX_BUS_NUM];
-u32 pbsdelay_per_pup[NUM_OF_PBS_MODES][MAX_INTERFACE_NUM][MAX_BUS_NUM];
+u32 pbsdelay_per_pup[NUM_OF_PBS_MODES][MAX_INTERFACE_NUM][MAX_BUS_NUM][MAX_CS_NUM];
 u8 adll_shift_lock[MAX_INTERFACE_NUM][MAX_BUS_NUM];
 u8 adll_shift_val[MAX_INTERFACE_NUM][MAX_BUS_NUM];
 enum hws_pattern pbs_pattern = PATTERN_VREF;
@@ -50,34 +44,33 @@ int ddr3_tip_pbs(u32 dev_num, enum pbs_dir pbs_mode)
 	int init_val = (search_dir == HWS_LOW2HIGH) ? 0 : iterations;
 	enum hws_edge_compare search_edge = EDGE_FP;
 	u32 pup = 0, bit = 0, if_id = 0, all_lock = 0, cs_num = 0;
-	int reg_addr = 0;
+	u32 reg_addr = 0;
 	u32 validation_val = 0;
 	u32 cs_enable_reg_val[MAX_INTERFACE_NUM];
 	u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
 	u8 temp = 0;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	/* save current cs enable reg val */
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 
 		/* save current cs enable reg val */
 		CHECK_STATUS(ddr3_tip_if_read
 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      CS_ENABLE_REG, cs_enable_reg_val, MASK_ALL_BITS));
+			      DUAL_DUNIT_CFG_REG, cs_enable_reg_val, MASK_ALL_BITS));
 
 		/* enable single cs */
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      CS_ENABLE_REG, (1 << 3), (1 << 3)));
+			      DUAL_DUNIT_CFG_REG, (1 << 3), (1 << 3)));
 	}
 
 	reg_addr = (pbs_mode == PBS_RX_MODE) ?
-		(READ_CENTRALIZATION_PHY_REG +
-		 (effective_cs * CS_REGISTER_ADDR_OFFSET)) :
-		(WRITE_CENTRALIZATION_PHY_REG +
-		 (effective_cs * CS_REGISTER_ADDR_OFFSET));
-	read_adll_value(nominal_adll, reg_addr, MASK_ALL_BITS);
+		CRX_PHY_REG(effective_cs) :
+		CTX_PHY_REG(effective_cs);
+	ddr3_tip_read_adll_value(dev_num, nominal_adll, reg_addr, MASK_ALL_BITS);
 
 	/* stage 1 shift ADLL */
 	ddr3_tip_ip_training(dev_num, ACCESS_TYPE_MULTICAST,
@@ -88,10 +81,10 @@ int ddr3_tip_pbs(u32 dev_num, enum pbs_dir pbs_mode)
 			     pbs_pattern, search_edge, CS_SINGLE, cs_num,
 			     train_status);
 	validation_val = (pbs_mode == PBS_RX_MODE) ? 0x1f : 0;
-	for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
-		VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+	for (pup = 0; pup < octets_per_if_num; pup++) {
+		VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup);
 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 			min_adll_per_pup[if_id][pup] =
 				(pbs_mode == PBS_RX_MODE) ? 0x1f : 0x3f;
 			pup_state[if_id][pup] = 0x3;
@@ -101,8 +94,8 @@ int ddr3_tip_pbs(u32 dev_num, enum pbs_dir pbs_mode)
 	}
 
 	/* EBA */
-	for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
-		VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+	for (pup = 0; pup < octets_per_if_num; pup++) {
+		VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup);
 		for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
 			CHECK_STATUS(ddr3_tip_if_read
 				     (dev_num, ACCESS_TYPE_MULTICAST,
@@ -112,7 +105,7 @@ int ddr3_tip_pbs(u32 dev_num, enum pbs_dir pbs_mode)
 				      res0, MASK_ALL_BITS));
 			for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
 			     if_id++) {
-				VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+				VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 				DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
 						 ("FP I/F %d, bit:%d, pup:%d res0 0x%x\n",
 						  if_id, bit, pup,
@@ -177,10 +170,10 @@ int ddr3_tip_pbs(u32 dev_num, enum pbs_dir pbs_mode)
 	}
 
 	/* EEBA */
-	for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
-		VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+	for (pup = 0; pup < octets_per_if_num; pup++) {
+		VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup);
 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 
 			if (pup_state[if_id][pup] != 4)
 				continue;
@@ -336,10 +329,10 @@ int ddr3_tip_pbs(u32 dev_num, enum pbs_dir pbs_mode)
 	}
 
 	/* Print Stage result */
-	for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
-		VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+	for (pup = 0; pup < octets_per_if_num; pup++) {
+		VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup);
 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 			DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
 					 ("FP I/F %d, ADLL Shift for EBA: pup[%d] Lock status = %d Lock Val = %d,%d\n",
 					  if_id, pup,
@@ -351,10 +344,10 @@ int ddr3_tip_pbs(u32 dev_num, enum pbs_dir pbs_mode)
 	DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,
 			 ("Update ADLL Shift of all pups:\n"));
 
-	for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
-		VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+	for (pup = 0; pup < octets_per_if_num; pup++) {
+		VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup);
 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 			if (adll_shift_lock[if_id][pup] != 1)
 				continue;
 			/* if pup not locked continue to next pup */
@@ -374,10 +367,10 @@ int ddr3_tip_pbs(u32 dev_num, enum pbs_dir pbs_mode)
 
 	/* PBS EEBA&EBA */
 	/* Start the Per Bit Skew search */
-	for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
-		VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+	for (pup = 0; pup < octets_per_if_num; pup++) {
+		VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup);
 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 			max_pbs_per_pup[if_id][pup] = 0x0;
 			min_pbs_per_pup[if_id][pup] = 0x1f;
 			for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
@@ -401,10 +394,10 @@ int ddr3_tip_pbs(u32 dev_num, enum pbs_dir pbs_mode)
 			     iterations, pbs_pattern, search_edge,
 			     CS_SINGLE, cs_num, train_status);
 
-	for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
-		VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+	for (pup = 0; pup < octets_per_if_num; pup++) {
+		VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup);
 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 			if (adll_shift_lock[if_id][pup] != 1) {
 				/* if pup not lock continue to next pup */
 				continue;
@@ -462,10 +455,10 @@ int ddr3_tip_pbs(u32 dev_num, enum pbs_dir pbs_mode)
 
 	/* Check all Pup lock */
 	all_lock = 1;
-	for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
-		VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+	for (pup = 0; pup < octets_per_if_num; pup++) {
+		VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup);
 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 			all_lock = all_lock * adll_shift_lock[if_id][pup];
 		}
 	}
@@ -479,11 +472,11 @@ int ddr3_tip_pbs(u32 dev_num, enum pbs_dir pbs_mode)
 		search_dir = (pbs_mode == PBS_RX_MODE) ? HWS_LOW2HIGH :
 			HWS_HIGH2LOW;
 		init_val = (search_dir == HWS_LOW2HIGH) ? 0 : iterations;
-		for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+		for (pup = 0; pup < octets_per_if_num; pup++) {
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup);
 			for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
 			     if_id++) {
-				VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+				VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 				if (adll_shift_lock[if_id][pup] == 1) {
 					/*if pup lock continue to next pup */
 					continue;
@@ -628,11 +621,11 @@ int ddr3_tip_pbs(u32 dev_num, enum pbs_dir pbs_mode)
 				     search_edge, CS_SINGLE, cs_num,
 				     train_status);
 
-		for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+		for (pup = 0; pup < octets_per_if_num; pup++) {
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup);
 			for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
 			     if_id++) {
-				VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+				VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 				for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
 					CHECK_STATUS(ddr3_tip_if_read
 						     (dev_num,
@@ -697,7 +690,7 @@ int ddr3_tip_pbs(u32 dev_num, enum pbs_dir pbs_mode)
 
 		/* Check all Pup state */
 		all_lock = 1;
-		for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
+		for (pup = 0; pup < octets_per_if_num; pup++) {
 			/*
 			 * DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,
 			 * ("pup_state[%d][%d] = %d\n",if_id,pup,pup_state
@@ -708,12 +701,12 @@ int ddr3_tip_pbs(u32 dev_num, enum pbs_dir pbs_mode)
 
 	/* END OF SBA */
 	/* Norm */
-	for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
-		VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+	for (pup = 0; pup < octets_per_if_num; pup++) {
+		VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup);
 		for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
 			for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
 			     if_id++) {
-				VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+				VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 				/* if pup not lock continue to next pup */
 				if (adll_shift_lock[if_id][pup] != 1) {
 					DEBUG_PBS_ENGINE(
@@ -754,9 +747,9 @@ int ddr3_tip_pbs(u32 dev_num, enum pbs_dir pbs_mode)
 
 	/* DQ PBS register update with the final result */
 	for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-		for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+		for (pup = 0; pup < octets_per_if_num; pup++) {
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup);
 
 			DEBUG_PBS_ENGINE(
 				DEBUG_LEVEL_INFO,
@@ -772,28 +765,32 @@ int ddr3_tip_pbs(u32 dev_num, enum pbs_dir pbs_mode)
 				pad_num = dq_map_table[
 					bit + pup * BUS_WIDTH_IN_BITS +
 					if_id * BUS_WIDTH_IN_BITS *
-					tm->num_of_bus_per_interface];
+					MAX_BUS_NUM];
 				DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,
 						 ("result_mat: %d ",
 						  result_mat[if_id][pup]
 						  [bit]));
 				reg_addr = (pbs_mode == PBS_RX_MODE) ?
-					(PBS_RX_PHY_REG + effective_cs * 0x10) :
-					(PBS_TX_PHY_REG + effective_cs * 0x10);
+					PBS_RX_PHY_REG(effective_cs, 0) :
+					PBS_TX_PHY_REG(effective_cs, 0);
 				CHECK_STATUS(ddr3_tip_bus_write
 					     (dev_num, ACCESS_TYPE_UNICAST,
 					      if_id, ACCESS_TYPE_UNICAST, pup,
 					      DDR_PHY_DATA, reg_addr + pad_num,
 					      result_mat[if_id][pup][bit]));
 			}
-			pbsdelay_per_pup[pbs_mode][if_id][pup] =
-				(max_pbs_per_pup[if_id][pup] ==
-				 min_pbs_per_pup[if_id][pup]) ?
-				TYPICAL_PBS_VALUE :
-				((max_adll_per_pup[if_id][pup] -
-				  min_adll_per_pup[if_id][pup]) * adll_tap /
-				 (max_pbs_per_pup[if_id][pup] -
-				  min_pbs_per_pup[if_id][pup]));
+
+			if (max_pbs_per_pup[if_id][pup] == min_pbs_per_pup[if_id][pup]) {
+				temp = TYPICAL_PBS_VALUE;
+			} else {
+				temp = ((max_adll_per_pup[if_id][pup] -
+					 min_adll_per_pup[if_id][pup]) *
+					adll_tap /
+					(max_pbs_per_pup[if_id][pup] -
+					 min_pbs_per_pup[if_id][pup]));
+			}
+			pbsdelay_per_pup[pbs_mode]
+			[if_id][pup][effective_cs] = temp;
 
 			/* RX results ready, write RX also */
 			if (pbs_mode == PBS_TX_MODE) {
@@ -843,18 +840,18 @@ int ddr3_tip_pbs(u32 dev_num, enum pbs_dir pbs_mode)
 			DEBUG_PBS_ENGINE(
 				DEBUG_LEVEL_INFO,
 				(", PBS tap=%d [psec] ==> skew observed = %d\n",
-				 pbsdelay_per_pup[pbs_mode][if_id][pup],
+				 temp,
 				 ((max_pbs_per_pup[if_id][pup] -
 				   min_pbs_per_pup[if_id][pup]) *
-				  pbsdelay_per_pup[pbs_mode][if_id][pup])));
+				 temp)));
 		}
 	}
 
 	/* Write back to the phy the default values */
 	reg_addr = (pbs_mode == PBS_RX_MODE) ?
-		(READ_CENTRALIZATION_PHY_REG + effective_cs * 4) :
-		(WRITE_CENTRALIZATION_PHY_REG + effective_cs * 4);
-	write_adll_value(nominal_adll, reg_addr);
+		CRX_PHY_REG(effective_cs) :
+		CTX_PHY_REG(effective_cs);
+	ddr3_tip_write_adll_value(dev_num, nominal_adll, reg_addr);
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
 		reg_addr = (pbs_mode == PBS_RX_MODE) ?
@@ -866,24 +863,29 @@ int ddr3_tip_pbs(u32 dev_num, enum pbs_dir pbs_mode)
 			      0));
 
 		/* restore cs enable value */
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 		CHECK_STATUS(ddr3_tip_if_write
 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
-			      CS_ENABLE_REG, cs_enable_reg_val[if_id],
+			      DUAL_DUNIT_CFG_REG, cs_enable_reg_val[if_id],
 			      MASK_ALL_BITS));
 	}
 
 	/* exit test mode */
 	CHECK_STATUS(ddr3_tip_if_write
 		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ODPG_WRITE_READ_MODE_ENABLE_REG, 0xffff, MASK_ALL_BITS));
+		      ODPG_WR_RD_MODE_ENA_REG, 0xffff, MASK_ALL_BITS));
+
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		/*
-		 * meaning that there is no VW exist at all (No lock at
-		 * the EBA ADLL shift@EBS)
-		 */
-		if (pup_state[if_id][pup] == 1)
-			return MV_FAIL;
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+		for (pup = 0; pup < octets_per_if_num; pup++) {
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup);
+			/*
+			 * no valid window found
+			 * (no lock at EBA ADLL shift at EBS)
+			 */
+			if (pup_state[if_id][pup] == 1)
+				return MV_FAIL;
+		}
 	}
 
 	return MV_OK;
@@ -913,14 +915,14 @@ int ddr3_tip_pbs_tx(u32 uidev_num)
 	return ddr3_tip_pbs(uidev_num, PBS_TX_MODE);
 }
 
-#ifndef EXCLUDE_SWITCH_DEBUG
+#ifdef DDR_VIEWER_TOOL
 /*
  * Print PBS Result
  */
 int ddr3_tip_print_all_pbs_result(u32 dev_num)
 {
 	u32 curr_cs;
-	u32 max_cs = hws_ddr3_tip_max_cs_get();
+	u32 max_cs = ddr3_tip_max_cs_get(dev_num);
 
 	for (curr_cs = 0; curr_cs < max_cs; curr_cs++) {
 		ddr3_tip_print_pbs_result(dev_num, curr_cs, PBS_RX_MODE);
@@ -937,21 +939,33 @@ int ddr3_tip_print_pbs_result(u32 dev_num, u32 cs_num, enum pbs_dir pbs_mode)
 {
 	u32 data_value = 0, bit = 0, if_id = 0, pup = 0;
 	u32 reg_addr = (pbs_mode == PBS_RX_MODE) ?
-		(PBS_RX_PHY_REG + cs_num * 0x10) :
-		(PBS_TX_PHY_REG + cs_num * 0x10);
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+		PBS_RX_PHY_REG(cs_num, 0) :
+		PBS_TX_PHY_REG(cs_num , 0);
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+
+	printf("%s,CS%d,PBS,ADLLRATIO,,,",
+	       (pbs_mode == PBS_RX_MODE) ? "Rx" : "Tx", cs_num);
 
+	for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+		for (pup = 0; pup < octets_per_if_num; pup++) {
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup);
+			printf("%d,",
+			       pbsdelay_per_pup[pbs_mode][if_id][pup][cs_num]);
+		}
+	}
 	printf("CS%d, %s ,PBS\n", cs_num,
 	       (pbs_mode == PBS_RX_MODE) ? "Rx" : "Tx");
 
 	for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
 		printf("%s, DQ", (pbs_mode == PBS_RX_MODE) ? "Rx" : "Tx");
 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+			VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 			printf("%d ,PBS,,, ", bit);
-			for (pup = 0; pup <= tm->num_of_bus_per_interface;
+			for (pup = 0; pup <= octets_per_if_num;
 			     pup++) {
-				VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+				VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup);
 				CHECK_STATUS(ddr3_tip_bus_read
 					     (dev_num, if_id,
 					      ACCESS_TYPE_UNICAST, pup,
@@ -966,7 +980,7 @@ int ddr3_tip_print_pbs_result(u32 dev_num, u32 cs_num, enum pbs_dir pbs_mode)
 
 	return MV_OK;
 }
-#endif
+#endif /* DDR_VIEWER_TOOL */
 
 /*
  * Fixup PBS Result
@@ -975,13 +989,14 @@ int ddr3_tip_clean_pbs_result(u32 dev_num, enum pbs_dir pbs_mode)
 {
 	u32 if_id, pup, bit;
 	u32 reg_addr = (pbs_mode == PBS_RX_MODE) ?
-		(PBS_RX_PHY_REG + effective_cs * 0x10) :
-		(PBS_TX_PHY_REG + effective_cs * 0x10);
-	struct hws_topology_map *tm = ddr3_get_topology_map();
+		PBS_RX_PHY_REG(effective_cs, 0) :
+		PBS_TX_PHY_REG(effective_cs, 0);
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 
 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-		for (pup = 0; pup <= tm->num_of_bus_per_interface; pup++) {
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+		for (pup = 0; pup <= octets_per_if_num; pup++) {
 			for (bit = 0; bit <= BUS_WIDTH_IN_BITS + 3; bit++) {
 				CHECK_STATUS(ddr3_tip_bus_write
 					     (dev_num, ACCESS_TYPE_UNICAST,
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_static.c b/drivers/ddr/marvell/a38x/ddr3_training_static.c
deleted file mode 100644
index 318634eb90dd..000000000000
--- a/drivers/ddr/marvell/a38x/ddr3_training_static.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- *
- * SPDX-License-Identifier:	GPL-2.0
- */
-
-#include <common.h>
-#include <spl.h>
-#include <asm/io.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/soc.h>
-
-#include "ddr3_init.h"
-
-/* Design Guidelines parameters */
-u32 g_zpri_data = 123;		/* controller data - P drive strength */
-u32 g_znri_data = 123;		/* controller data - N drive strength */
-u32 g_zpri_ctrl = 74;		/* controller C/A - P drive strength */
-u32 g_znri_ctrl = 74;		/* controller C/A - N drive strength */
-u32 g_zpodt_data = 45;		/* controller data - P ODT */
-u32 g_znodt_data = 45;		/* controller data - N ODT */
-u32 g_zpodt_ctrl = 45;		/* controller data - P ODT */
-u32 g_znodt_ctrl = 45;		/* controller data - N ODT */
-u32 g_odt_config_2cs = 0x120012;
-u32 g_odt_config_1cs = 0x10000;
-u32 g_rtt_nom = 0x44;
-u32 g_dic = 0x2;
-
-
-/*
- * Configure phy (called by static init controller) for static flow
- */
-int ddr3_tip_configure_phy(u32 dev_num)
-{
-	u32 if_id, phy_id;
-	struct hws_topology_map *tm = ddr3_get_topology_map();
-
-	CHECK_STATUS(ddr3_tip_bus_write
-		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA,
-		      PAD_ZRI_CALIB_PHY_REG,
-		      ((0x7f & g_zpri_data) << 7 | (0x7f & g_znri_data))));
-	CHECK_STATUS(ddr3_tip_bus_write
-		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL,
-		      PAD_ZRI_CALIB_PHY_REG,
-		      ((0x7f & g_zpri_ctrl) << 7 | (0x7f & g_znri_ctrl))));
-	CHECK_STATUS(ddr3_tip_bus_write
-		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA,
-		      PAD_ODT_CALIB_PHY_REG,
-		      ((0x3f & g_zpodt_data) << 6 | (0x3f & g_znodt_data))));
-	CHECK_STATUS(ddr3_tip_bus_write
-		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL,
-		      PAD_ODT_CALIB_PHY_REG,
-		      ((0x3f & g_zpodt_ctrl) << 6 | (0x3f & g_znodt_ctrl))));
-
-	CHECK_STATUS(ddr3_tip_bus_write
-		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA,
-		      PAD_PRE_DISABLE_PHY_REG, 0));
-	CHECK_STATUS(ddr3_tip_bus_write
-		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA,
-		      CMOS_CONFIG_PHY_REG, 0));
-	CHECK_STATUS(ddr3_tip_bus_write
-		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL,
-		      CMOS_CONFIG_PHY_REG, 0));
-
-	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
-		/* check if the interface is enabled */
-		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
-
-		for (phy_id = 0;
-		     phy_id < tm->num_of_bus_per_interface;
-		     phy_id++) {
-			VALIDATE_ACTIVE(tm->bus_act_mask, phy_id);
-			/* Vref & clamp */
-			CHECK_STATUS(ddr3_tip_bus_read_modify_write
-				     (dev_num, ACCESS_TYPE_UNICAST,
-				      if_id, phy_id, DDR_PHY_DATA,
-				      PAD_CONFIG_PHY_REG,
-				      ((clamp_tbl[if_id] << 4) | vref),
-				      ((0x7 << 4) | 0x7)));
-			/* clamp not relevant for control */
-			CHECK_STATUS(ddr3_tip_bus_read_modify_write
-				     (dev_num, ACCESS_TYPE_UNICAST,
-				      if_id, phy_id, DDR_PHY_CONTROL,
-				      PAD_CONFIG_PHY_REG, 0x4, 0x7));
-		}
-	}
-
-	CHECK_STATUS(ddr3_tip_bus_write
-		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
-		      ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0x90,
-		      0x6002));
-
-	return MV_OK;
-}
diff --git a/drivers/ddr/marvell/a38x/ddr_ml_wrapper.h b/drivers/ddr/marvell/a38x/ddr_ml_wrapper.h
new file mode 100644
index 000000000000..de55632fee69
--- /dev/null
+++ b/drivers/ddr/marvell/a38x/ddr_ml_wrapper.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#ifndef _DDR_ML_WRAPPER_H
+#define _DDR_ML_WRAPPER_H
+
+#include <common.h>
+#include <i2c.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X)
+#define INTER_REGS_BASE	SOC_REGS_PHY_BASE
+#endif
+
+/*
+ * MV_DEBUG_INIT need to be defines, otherwise the output of the
+ * DDR2 training code is not complete and misleading
+ */
+#define MV_DEBUG_INIT
+
+#ifdef MV_DEBUG_INIT
+#define DEBUG_INIT_S(s)			puts(s)
+#define DEBUG_INIT_D(d, l)		printf("%x", d)
+#define DEBUG_INIT_D_10(d, l)		printf("%d", d)
+#else
+#define DEBUG_INIT_S(s)
+#define DEBUG_INIT_D(d, l)
+#define DEBUG_INIT_D_10(d, l)
+#endif
+
+#ifdef MV_DEBUG_INIT_FULL
+#define DEBUG_INIT_FULL_S(s)		puts(s)
+#define DEBUG_INIT_FULL_D(d, l)		printf("%x", d)
+#define DEBUG_INIT_FULL_D_10(d, l)	printf("%d", d)
+#define DEBUG_WR_REG(reg, val) \
+	{ DEBUG_INIT_S("Write Reg: 0x"); DEBUG_INIT_D((reg), 8); \
+	  DEBUG_INIT_S("= "); DEBUG_INIT_D((val), 8); DEBUG_INIT_S("\n"); }
+#define DEBUG_RD_REG(reg, val) \
+	{ DEBUG_INIT_S("Read  Reg: 0x"); DEBUG_INIT_D((reg), 8); \
+	  DEBUG_INIT_S("= "); DEBUG_INIT_D((val), 8); DEBUG_INIT_S("\n"); }
+#else
+#define DEBUG_INIT_FULL_S(s)
+#define DEBUG_INIT_FULL_D(d, l)
+#define DEBUG_INIT_FULL_D_10(d, l)
+#define DEBUG_WR_REG(reg, val)
+#define DEBUG_RD_REG(reg, val)
+#endif
+
+#define DEBUG_INIT_FULL_C(s, d, l)			\
+	{ DEBUG_INIT_FULL_S(s);				\
+	  DEBUG_INIT_FULL_D(d, l);			\
+	  DEBUG_INIT_FULL_S("\n"); }
+#define DEBUG_INIT_C(s, d, l) \
+	{ DEBUG_INIT_S(s); DEBUG_INIT_D(d, l); DEBUG_INIT_S("\n"); }
+
+/*
+ * Debug (Enable/Disable modules) and Error report
+ */
+
+#ifdef BASIC_DEBUG
+#define MV_DEBUG_WL
+#define MV_DEBUG_RL
+#define MV_DEBUG_DQS_RESULTS
+#endif
+
+#ifdef FULL_DEBUG
+#define MV_DEBUG_WL
+#define MV_DEBUG_RL
+#define MV_DEBUG_DQS
+
+#define MV_DEBUG_PBS
+#define MV_DEBUG_DFS
+#define MV_DEBUG_MAIN_FULL
+#define MV_DEBUG_DFS_FULL
+#define MV_DEBUG_DQS_FULL
+#define MV_DEBUG_RL_FULL
+#define MV_DEBUG_WL_FULL
+#endif
+
+
+/* The following is a list of Marvell status */
+#define MV_ERROR	(-1)
+#define MV_OK		(0x00)	/* Operation succeeded                   */
+#define MV_FAIL		(0x01)	/* Operation failed                      */
+#define MV_BAD_VALUE	(0x02)	/* Illegal value (general)               */
+#define MV_OUT_OF_RANGE	(0x03)	/* The value is out of range             */
+#define MV_BAD_PARAM	(0x04)	/* Illegal parameter in function called  */
+#define MV_BAD_PTR	(0x05)	/* Illegal pointer value                 */
+#define MV_BAD_SIZE	(0x06)	/* Illegal size                          */
+#define MV_BAD_STATE	(0x07)	/* Illegal state of state machine        */
+#define MV_SET_ERROR	(0x08)	/* Set operation failed                  */
+#define MV_GET_ERROR	(0x09)	/* Get operation failed                  */
+#define MV_CREATE_ERROR	(0x0a)	/* Fail while creating an item           */
+#define MV_NOT_FOUND	(0x0b)	/* Item not found                        */
+#define MV_NO_MORE	(0x0c)	/* No more items found                   */
+#define MV_NO_SUCH	(0x0d)	/* No such item                          */
+#define MV_TIMEOUT	(0x0e)	/* Time Out                              */
+#define MV_NO_CHANGE	(0x0f)	/* Parameter(s) is already in this value */
+#define MV_NOT_SUPPORTED (0x10)	/* This request is not support           */
+#define MV_NOT_IMPLEMENTED (0x11) /* Request supported but not implemented*/
+#define MV_NOT_INITIALIZED (0x12) /* The item is not initialized          */
+#define MV_NO_RESOURCE	(0x13)	/* Resource not available (memory ...)   */
+#define MV_FULL		(0x14)	/* Item is full (Queue or table etc...)  */
+#define MV_EMPTY	(0x15)	/* Item is empty (Queue or table etc...) */
+#define MV_INIT_ERROR	(0x16)	/* Error occured while INIT process      */
+#define MV_HW_ERROR	(0x17)	/* Hardware error                        */
+#define MV_TX_ERROR	(0x18)	/* Transmit operation not succeeded      */
+#define MV_RX_ERROR	(0x19)	/* Recieve operation not succeeded       */
+#define MV_NOT_READY	(0x1a)	/* The other side is not ready yet       */
+#define MV_ALREADY_EXIST (0x1b)	/* Tried to create existing item         */
+#define MV_OUT_OF_CPU_MEM   (0x1c) /* Cpu memory allocation failed.      */
+#define MV_NOT_STARTED	(0x1d)	/* Not started yet                       */
+#define MV_BUSY		(0x1e)	/* Item is busy.                         */
+#define MV_TERMINATE	(0x1f)	/* Item terminates it's work.            */
+#define MV_NOT_ALIGNED	(0x20)	/* Wrong alignment                       */
+#define MV_NOT_ALLOWED	(0x21)	/* Operation NOT allowed                 */
+#define MV_WRITE_PROTECT (0x22)	/* Write protected                       */
+#define MV_INVALID	(int)(-1)
+
+/*
+ * Accessor functions for the registers
+ */
+static inline void reg_write(u32 addr, u32 val)
+{
+	writel(val, INTER_REGS_BASE + addr);
+}
+
+static inline u32 reg_read(u32 addr)
+{
+	return readl(INTER_REGS_BASE + addr);
+}
+
+static inline void reg_bit_set(u32 addr, u32 mask)
+{
+	setbits_le32(INTER_REGS_BASE + addr, mask);
+}
+
+static inline void reg_bit_clr(u32 addr, u32 mask)
+{
+	clrbits_le32(INTER_REGS_BASE + addr, mask);
+}
+
+#endif /* _DDR_ML_WRAPPER_H */
diff --git a/drivers/ddr/marvell/a38x/ddr_topology_def.h b/drivers/ddr/marvell/a38x/ddr_topology_def.h
index 229c3a127a83..8fd0361dfbd4 100644
--- a/drivers/ddr/marvell/a38x/ddr_topology_def.h
+++ b/drivers/ddr/marvell/a38x/ddr_topology_def.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) Marvell International Ltd. and its affiliates
  *
- * SPDX-License-Identifier:     GPL-2.0
+ * SPDX-License-Identifier:	GPL-2.0
  */
 
 #ifndef _DDR_TOPOLOGY_DEF_H
@@ -10,38 +10,13 @@
 #include "ddr3_training_ip_def.h"
 #include "ddr3_topology_def.h"
 
-#if defined(CONFIG_ARMADA_38X)
-#include "ddr3_a38x.h"
+#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X)
+#include "mv_ddr_plat.h"
 #endif
 
-/* bus width in bits */
-enum hws_bus_width {
-	BUS_WIDTH_4,
-	BUS_WIDTH_8,
-	BUS_WIDTH_16,
-	BUS_WIDTH_32
-};
-
-enum hws_temperature {
-	HWS_TEMP_LOW,
-	HWS_TEMP_NORMAL,
-	HWS_TEMP_HIGH
-};
-
-enum hws_mem_size {
-	MEM_512M,
-	MEM_1G,
-	MEM_2G,
-	MEM_4G,
-	MEM_8G,
-	MEM_SIZE_LAST
-};
-
-enum hws_timing {
-	HWS_TIM_DEFAULT,
-	HWS_TIM_1T,
-	HWS_TIM_2T
-};
+#include "mv_ddr_topology.h"
+#include "mv_ddr_spd.h"
+#include "ddr3_logging_def.h"
 
 struct bus_params {
 	/* Chip Select (CS) bitmask (bits 0-CS0, bit 1- CS1 ...) */
@@ -67,11 +42,11 @@ struct if_params {
 	/* Speed Bin Table */
 	enum hws_speed_bin speed_bin_index;
 
-	/* bus width of memory */
-	enum hws_bus_width bus_width;
+	/* sdram device width */
+	enum mv_ddr_dev_width bus_width;
 
-	/* Bus memory size (MBit) */
-	enum hws_mem_size memory_size;
+	/* total sdram capacity per die, megabits */
+	enum mv_ddr_die_capacity memory_size;
 
 	/* The DDR frequency for each interfaces */
 	enum hws_ddr_freq memory_freq;
@@ -89,33 +64,49 @@ struct if_params {
 	u8 cas_l;
 
 	/* operation temperature */
-	enum hws_temperature interface_temp;
-
-	/* 2T vs 1T mode (by default computed from number of CSs) */
-	enum hws_timing timing;
+	enum mv_ddr_temperature interface_temp;
 };
 
-struct hws_topology_map {
+struct mv_ddr_topology_map {
+	/* debug level configuration */
+	enum mv_ddr_debug_level debug_level;
+
 	/* Number of interfaces (default is 12) */
 	u8 if_act_mask;
 
 	/* Controller configuration per interface */
 	struct if_params interface_params[MAX_INTERFACE_NUM];
 
-	/* BUS per interface (default is 4) */
-	u8 num_of_bus_per_interface;
-
 	/* Bit mask for active buses */
-	u8 bus_act_mask;
+	u16 bus_act_mask;
+
+	/* source of ddr configuration data */
+	enum mv_ddr_cfg_src cfg_src;
+
+	/* raw spd data */
+	union mv_ddr_spd_data spd_data;
+
+	/* timing parameters */
+	unsigned int timing_data[MV_DDR_TDATA_LAST];
 };
 
 /* DDR3 training global configuration parameters */
 struct tune_train_params {
 	u32 ck_delay;
-	u32 ck_delay_16;
-	u32 p_finger;
-	u32 n_finger;
 	u32 phy_reg3_val;
+	u32 g_zpri_data;
+	u32 g_znri_data;
+	u32 g_zpri_ctrl;
+	u32 g_znri_ctrl;
+	u32 g_zpodt_data;
+	u32 g_znodt_data;
+	u32 g_zpodt_ctrl;
+	u32 g_znodt_ctrl;
+	u32 g_dic;
+	u32 g_odt_config;
+	u32 g_rtt_nom;
+	u32 g_rtt_wr;
+	u32 g_rtt_park;
 };
 
 #endif /* _DDR_TOPOLOGY_DEF_H */
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_build_message.c b/drivers/ddr/marvell/a38x/mv_ddr_build_message.c
new file mode 100644
index 000000000000..8e60448318f2
--- /dev/null
+++ b/drivers/ddr/marvell/a38x/mv_ddr_build_message.c
@@ -0,0 +1 @@
+const char mv_ddr_build_message[] = "";       const char mv_ddr_version_string[] = "mv_ddr: mv_ddr-armada-17.10.4";
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_common.c b/drivers/ddr/marvell/a38x/mv_ddr_common.c
new file mode 100644
index 000000000000..25c452a469c1
--- /dev/null
+++ b/drivers/ddr/marvell/a38x/mv_ddr_common.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include "mv_ddr_common.h"
+#include "ddr_ml_wrapper.h"
+
+void mv_ddr_ver_print(void)
+{
+	printf("%s %s\n", mv_ddr_version_string, mv_ddr_build_message);
+}
+
+/* ceiling division for positive integers */
+unsigned int ceil_div(unsigned int x, unsigned int y)
+{
+	return (x % y) ? (x / y + 1) : (x / y);
+}
+
+/*
+ * time to number of clocks calculation based on the rounding algorithm
+ * using 97.4% inverse factor per JEDEC Standard No. 21-C, 4.1.2.L-4:
+ * Serial Presence Detect (SPD) for DDR4 SDRAM Modules
+ */
+unsigned int time_to_nclk(unsigned int t, unsigned int tclk)
+{
+	/* t & tclk parameters are in ps */
+	return ((unsigned long)t * 1000 / tclk + 974) / 1000;
+}
+
+/* round division of two positive integers to the nearest whole number */
+int round_div(unsigned int dividend, unsigned int divisor, unsigned int *quotient)
+{
+	if (quotient == NULL) {
+		printf("%s: error: NULL quotient pointer found\n", __func__);
+		return MV_FAIL;
+	}
+
+	if (divisor == 0) {
+		printf("%s: error: division by zero\n", __func__);
+		return MV_FAIL;
+	} else {
+		*quotient = (dividend + divisor / 2) / divisor;
+	}
+
+	return MV_OK;
+}
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_common.h b/drivers/ddr/marvell/a38x/mv_ddr_common.h
new file mode 100644
index 000000000000..edf4c4ca251f
--- /dev/null
+++ b/drivers/ddr/marvell/a38x/mv_ddr_common.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#ifndef _MV_DDR_COMMON_H
+#define _MV_DDR_COMMON_H
+
+extern const char mv_ddr_build_message[];
+extern const char mv_ddr_version_string[];
+
+#define MV_DDR_NUM_BITS_IN_BYTE	8
+#define MV_DDR_MEGA_BITS	(1024 * 1024)
+#define MV_DDR_32_BITS_MASK	0xffffffff
+
+unsigned int ceil_div(unsigned int x, unsigned int y);
+unsigned int time_to_nclk(unsigned int t, unsigned int tclk);
+int round_div(unsigned int dividend, unsigned int divisor, unsigned int *quotient);
+
+#endif /* _MV_DDR_COMMON_H */
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_plat.c b/drivers/ddr/marvell/a38x/mv_ddr_plat.c
new file mode 100644
index 000000000000..058e262a61ad
--- /dev/null
+++ b/drivers/ddr/marvell/a38x/mv_ddr_plat.c
@@ -0,0 +1,1456 @@
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include "ddr3_init.h"
+
+#include "mv_ddr_sys_env_lib.h"
+
+#define DDR_INTERFACES_NUM		1
+#define DDR_INTERFACE_OCTETS_NUM	5
+
+/*
+ * 1. L2 filter should be set at binary header to 0xD000000,
+ *    to avoid conflict with internal register IO.
+ * 2. U-Boot modifies internal registers base to 0xf100000,
+ *    and than should update L2 filter accordingly to 0xf000000 (3.75 GB)
+ */
+#define L2_FILTER_FOR_MAX_MEMORY_SIZE	0xC0000000 /* temporary limit l2 filter to 3gb (LSP issue) */
+#define ADDRESS_FILTERING_END_REGISTER	0x8c04
+
+#define DYNAMIC_CS_SIZE_CONFIG
+#define DISABLE_L2_FILTERING_DURING_DDR_TRAINING
+
+/* Termal Sensor Registers */
+#define TSEN_CONTROL_LSB_REG		0xE4070
+#define TSEN_CONTROL_LSB_TC_TRIM_OFFSET	0
+#define TSEN_CONTROL_LSB_TC_TRIM_MASK	(0x7 << TSEN_CONTROL_LSB_TC_TRIM_OFFSET)
+#define TSEN_CONTROL_MSB_REG		0xE4074
+#define TSEN_CONTROL_MSB_RST_OFFSET	8
+#define TSEN_CONTROL_MSB_RST_MASK	(0x1 << TSEN_CONTROL_MSB_RST_OFFSET)
+#define TSEN_STATUS_REG			0xe4078
+#define TSEN_STATUS_READOUT_VALID_OFFSET	10
+#define TSEN_STATUS_READOUT_VALID_MASK	(0x1 <<				\
+					 TSEN_STATUS_READOUT_VALID_OFFSET)
+#define TSEN_STATUS_TEMP_OUT_OFFSET	0
+#define TSEN_STATUS_TEMP_OUT_MASK	(0x3ff << TSEN_STATUS_TEMP_OUT_OFFSET)
+
+static struct dlb_config ddr3_dlb_config_table[] = {
+	{DLB_CTRL_REG, 0x2000005c},
+	{DLB_BUS_OPT_WT_REG, 0x00880000},
+	{DLB_AGING_REG, 0x0f7f007f},
+	{DLB_EVICTION_CTRL_REG, 0x0000129f},
+	{DLB_EVICTION_TIMERS_REG, 0x00ff0000},
+	{DLB_WTS_DIFF_CS_REG, 0x04030802},
+	{DLB_WTS_DIFF_BG_REG, 0x00000a02},
+	{DLB_WTS_SAME_BG_REG, 0x09000a01},
+	{DLB_WTS_CMDS_REG, 0x00020005},
+	{DLB_WTS_ATTR_PRIO_REG, 0x00060f10},
+	{DLB_QUEUE_MAP_REG, 0x00000543},
+	{DLB_SPLIT_REG, 0x00000000},
+	{DLB_USER_CMD_REG, 0x00000000},
+	{0x0, 0x0}
+};
+
+static struct dlb_config *sys_env_dlb_config_ptr_get(void)
+{
+	return &ddr3_dlb_config_table[0];
+}
+
+static u8 a38x_bw_per_freq[DDR_FREQ_LAST] = {
+	0x3,			/* DDR_FREQ_100 */
+	0x4,			/* DDR_FREQ_400 */
+	0x4,			/* DDR_FREQ_533 */
+	0x5,			/* DDR_FREQ_667 */
+	0x5,			/* DDR_FREQ_800 */
+	0x5,			/* DDR_FREQ_933 */
+	0x5,			/* DDR_FREQ_1066 */
+	0x3,			/* DDR_FREQ_311 */
+	0x3,			/* DDR_FREQ_333 */
+	0x4,			/* DDR_FREQ_467 */
+	0x5,			/* DDR_FREQ_850 */
+	0x5,			/* DDR_FREQ_600 */
+	0x3,			/* DDR_FREQ_300 */
+	0x5,			/* DDR_FREQ_900 */
+	0x3,			/* DDR_FREQ_360 */
+	0x5			/* DDR_FREQ_1000 */
+};
+
+static u8 a38x_rate_per_freq[DDR_FREQ_LAST] = {
+	0x1,			/* DDR_FREQ_100 */
+	0x2,			/* DDR_FREQ_400 */
+	0x2,			/* DDR_FREQ_533 */
+	0x2,			/* DDR_FREQ_667 */
+	0x2,			/* DDR_FREQ_800 */
+	0x3,			/* DDR_FREQ_933 */
+	0x3,			/* DDR_FREQ_1066 */
+	0x1,			/* DDR_FREQ_311 */
+	0x1,			/* DDR_FREQ_333 */
+	0x2,			/* DDR_FREQ_467 */
+	0x2,			/* DDR_FREQ_850 */
+	0x2,			/* DDR_FREQ_600 */
+	0x1,			/* DDR_FREQ_300 */
+	0x2,			/* DDR_FREQ_900 */
+	0x1,			/* DDR_FREQ_360 */
+	0x2			/* DDR_FREQ_1000 */
+};
+
+static u16 a38x_vco_freq_per_sar_ref_clk_25_mhz[] = {
+	666,			/* 0 */
+	1332,
+	800,
+	1600,
+	1066,
+	2132,
+	1200,
+	2400,
+	1332,
+	1332,
+	1500,
+	1500,
+	1600,			/* 12 */
+	1600,
+	1700,
+	1700,
+	1866,
+	1866,
+	1800,			/* 18 */
+	2000,
+	2000,
+	4000,
+	2132,
+	2132,
+	2300,
+	2300,
+	2400,
+	2400,
+	2500,
+	2500,
+	800
+};
+
+static u16 a38x_vco_freq_per_sar_ref_clk_40_mhz[] = {
+	666,			/* 0 */
+	1332,
+	800,
+	800,			/* 0x3 */
+	1066,
+	1066,			/* 0x5 */
+	1200,
+	2400,
+	1332,
+	1332,
+	1500,			/* 10 */
+	1600,			/* 0xB */
+	1600,
+	1600,
+	1700,
+	1560,			/* 0xF */
+	1866,
+	1866,
+	1800,
+	2000,
+	2000,			/* 20 */
+	4000,
+	2132,
+	2132,
+	2300,
+	2300,
+	2400,
+	2400,
+	2500,
+	2500,
+	1800			/* 30 - 0x1E */
+};
+
+
+static u32 async_mode_at_tf;
+
+static u32 dq_bit_map_2_phy_pin[] = {
+	1, 0, 2, 6, 9, 8, 3, 7,	/* 0 */
+	8, 9, 1, 7, 2, 6, 3, 0,	/* 1 */
+	3, 9, 7, 8, 1, 0, 2, 6,	/* 2 */
+	1, 0, 6, 2, 8, 3, 7, 9,	/* 3 */
+	0, 1, 2, 9, 7, 8, 3, 6,	/* 4 */
+};
+
+void mv_ddr_mem_scrubbing(void)
+{
+}
+
+static int ddr3_tip_a38x_set_divider(u8 dev_num, u32 if_id,
+				     enum hws_ddr_freq freq);
+
+/*
+ * Read temperature TJ value
+ */
+static u32 ddr3_ctrl_get_junc_temp(u8 dev_num)
+{
+	int reg = 0;
+
+	/* Initiates TSEN hardware reset once */
+	if ((reg_read(TSEN_CONTROL_MSB_REG) & TSEN_CONTROL_MSB_RST_MASK) == 0) {
+		reg_bit_set(TSEN_CONTROL_MSB_REG, TSEN_CONTROL_MSB_RST_MASK);
+		/* set Tsen Tc Trim to correct default value (errata #132698) */
+		reg = reg_read(TSEN_CONTROL_LSB_REG);
+		reg &= ~TSEN_CONTROL_LSB_TC_TRIM_MASK;
+		reg |= 0x3 << TSEN_CONTROL_LSB_TC_TRIM_OFFSET;
+		reg_write(TSEN_CONTROL_LSB_REG, reg);
+	}
+	mdelay(10);
+
+	/* Check if the readout field is valid */
+	if ((reg_read(TSEN_STATUS_REG) & TSEN_STATUS_READOUT_VALID_MASK) == 0) {
+		printf("%s: TSEN not ready\n", __func__);
+		return 0;
+	}
+
+	reg = reg_read(TSEN_STATUS_REG);
+	reg = (reg & TSEN_STATUS_TEMP_OUT_MASK) >> TSEN_STATUS_TEMP_OUT_OFFSET;
+
+	return ((((10000 * reg) / 21445) * 1000) - 272674) / 1000;
+}
+
+/*
+ * Name:     ddr3_tip_a38x_get_freq_config.
+ * Desc:
+ * Args:
+ * Notes:
+ * Returns:  MV_OK if success, other error code if fail.
+ */
+static int ddr3_tip_a38x_get_freq_config(u8 dev_num, enum hws_ddr_freq freq,
+				  struct hws_tip_freq_config_info
+				  *freq_config_info)
+{
+	if (a38x_bw_per_freq[freq] == 0xff)
+		return MV_NOT_SUPPORTED;
+
+	if (freq_config_info == NULL)
+		return MV_BAD_PARAM;
+
+	freq_config_info->bw_per_freq = a38x_bw_per_freq[freq];
+	freq_config_info->rate_per_freq = a38x_rate_per_freq[freq];
+	freq_config_info->is_supported = 1;
+
+	return MV_OK;
+}
+
+static void dunit_read(u32 addr, u32 mask, u32 *data)
+{
+	*data = reg_read(addr) & mask;
+}
+
+static void dunit_write(u32 addr, u32 mask, u32 data)
+{
+	u32 reg_val = data;
+
+	if (mask != MASK_ALL_BITS) {
+		dunit_read(addr, MASK_ALL_BITS, &reg_val);
+		reg_val &= (~mask);
+		reg_val |= (data & mask);
+	}
+
+	reg_write(addr, reg_val);
+}
+
+#define ODPG_ENABLE_REG				0x186d4
+#define ODPG_EN_OFFS				0
+#define ODPG_EN_MASK				0x1
+#define ODPG_EN_ENA				1
+#define ODPG_EN_DONE				0
+#define ODPG_DIS_OFFS				8
+#define ODPG_DIS_MASK				0x1
+#define ODPG_DIS_DIS				1
+void mv_ddr_odpg_enable(void)
+{
+	dunit_write(ODPG_ENABLE_REG,
+		    ODPG_EN_MASK << ODPG_EN_OFFS,
+		    ODPG_EN_ENA << ODPG_EN_OFFS);
+}
+
+void mv_ddr_odpg_disable(void)
+{
+	dunit_write(ODPG_ENABLE_REG,
+		    ODPG_DIS_MASK << ODPG_DIS_OFFS,
+		    ODPG_DIS_DIS << ODPG_DIS_OFFS);
+}
+
+void mv_ddr_odpg_done_clr(void)
+{
+	return;
+}
+
+int mv_ddr_is_odpg_done(u32 count)
+{
+	u32 i, data;
+
+	for (i = 0; i < count; i++) {
+		dunit_read(ODPG_ENABLE_REG, MASK_ALL_BITS, &data);
+		if (((data >> ODPG_EN_OFFS) & ODPG_EN_MASK) ==
+		     ODPG_EN_DONE)
+			break;
+	}
+
+	if (i >= count) {
+		printf("%s: timeout\n", __func__);
+		return MV_FAIL;
+	}
+
+	return MV_OK;
+}
+
+void mv_ddr_training_enable(void)
+{
+	dunit_write(GLOB_CTRL_STATUS_REG,
+		    TRAINING_TRIGGER_MASK << TRAINING_TRIGGER_OFFS,
+		    TRAINING_TRIGGER_ENA << TRAINING_TRIGGER_OFFS);
+}
+
+#define DRAM_INIT_CTRL_STATUS_REG	0x18488
+#define TRAINING_TRIGGER_OFFS		0
+#define TRAINING_TRIGGER_MASK		0x1
+#define TRAINING_TRIGGER_ENA		1
+#define TRAINING_DONE_OFFS		1
+#define TRAINING_DONE_MASK		0x1
+#define TRAINING_DONE_DONE		1
+#define TRAINING_DONE_NOT_DONE		0
+#define TRAINING_RESULT_OFFS		2
+#define TRAINING_RESULT_MASK		0x1
+#define TRAINING_RESULT_PASS		0
+#define TRAINING_RESULT_FAIL		1
+int mv_ddr_is_training_done(u32 count, u32 *result)
+{
+	u32 i, data;
+
+	if (result == NULL) {
+		printf("%s: NULL result pointer found\n", __func__);
+		return MV_FAIL;
+	}
+
+	for (i = 0; i < count; i++) {
+		dunit_read(DRAM_INIT_CTRL_STATUS_REG, MASK_ALL_BITS, &data);
+		if (((data >> TRAINING_DONE_OFFS) & TRAINING_DONE_MASK) ==
+		     TRAINING_DONE_DONE)
+			break;
+	}
+
+	if (i >= count) {
+		printf("%s: timeout\n", __func__);
+		return MV_FAIL;
+	}
+
+	*result = (data >> TRAINING_RESULT_OFFS) & TRAINING_RESULT_MASK;
+
+	return MV_OK;
+}
+
+#define DM_PAD	10
+u32 mv_ddr_dm_pad_get(void)
+{
+	return DM_PAD;
+}
+
+/*
+ * Name:     ddr3_tip_a38x_select_ddr_controller.
+ * Desc:     Enable/Disable access to Marvell's server.
+ * Args:     dev_num     - device number
+ *           enable        - whether to enable or disable the server
+ * Notes:
+ * Returns:  MV_OK if success, other error code if fail.
+ */
+static int ddr3_tip_a38x_select_ddr_controller(u8 dev_num, int enable)
+{
+	u32 reg;
+
+	reg = reg_read(DUAL_DUNIT_CFG_REG);
+
+	if (enable)
+		reg |= (1 << 6);
+	else
+		reg &= ~(1 << 6);
+
+	reg_write(DUAL_DUNIT_CFG_REG, reg);
+
+	return MV_OK;
+}
+
+static u8 ddr3_tip_clock_mode(u32 frequency)
+{
+	if ((frequency == DDR_FREQ_LOW_FREQ) || (freq_val[frequency] <= 400))
+		return 1;
+
+	return 2;
+}
+
+static int mv_ddr_sar_freq_get(int dev_num, enum hws_ddr_freq *freq)
+{
+	u32 reg, ref_clk_satr;
+
+	/* Read sample@reset setting */
+	reg = (reg_read(REG_DEVICE_SAR1_ADDR) >>
+	       RST2_CPU_DDR_CLOCK_SELECT_IN_OFFSET) &
+		RST2_CPU_DDR_CLOCK_SELECT_IN_MASK;
+
+	ref_clk_satr = reg_read(DEVICE_SAMPLE_AT_RESET2_REG);
+	if (((ref_clk_satr >> DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_OFFSET) & 0x1) ==
+	    DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_25MHZ) {
+		switch (reg) {
+		case 0x1:
+			DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR,
+					      ("Warning: Unsupported freq mode for 333Mhz configured(%d)\n",
+					      reg));
+			/* fallthrough */
+		case 0x0:
+			*freq = DDR_FREQ_333;
+			break;
+		case 0x3:
+			DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR,
+					      ("Warning: Unsupported freq mode for 400Mhz configured(%d)\n",
+					      reg));
+			/* fallthrough */
+		case 0x2:
+			*freq = DDR_FREQ_400;
+			break;
+		case 0xd:
+			DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR,
+					      ("Warning: Unsupported freq mode for 533Mhz configured(%d)\n",
+					      reg));
+			/* fallthrough */
+		case 0x4:
+			*freq = DDR_FREQ_533;
+			break;
+		case 0x6:
+			*freq = DDR_FREQ_600;
+			break;
+		case 0x11:
+		case 0x14:
+			DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR,
+					      ("Warning: Unsupported freq mode for 667Mhz configured(%d)\n",
+					      reg));
+			/* fallthrough */
+		case 0x8:
+			*freq = DDR_FREQ_667;
+			break;
+		case 0x15:
+		case 0x1b:
+			DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR,
+					      ("Warning: Unsupported freq mode for 800Mhz configured(%d)\n",
+					      reg));
+			/* fallthrough */
+		case 0xc:
+			*freq = DDR_FREQ_800;
+			break;
+		case 0x10:
+			*freq = DDR_FREQ_933;
+			break;
+		case 0x12:
+			*freq = DDR_FREQ_900;
+			break;
+		case 0x13:
+			*freq = DDR_FREQ_933;
+			break;
+		default:
+			*freq = 0;
+			return MV_NOT_SUPPORTED;
+		}
+	} else { /* REFCLK 40MHz case */
+		switch (reg) {
+		case 0x3:
+			*freq = DDR_FREQ_400;
+			break;
+		case 0x5:
+			*freq = DDR_FREQ_533;
+			break;
+		case 0xb:
+			*freq = DDR_FREQ_800;
+			break;
+		case 0x1e:
+			*freq = DDR_FREQ_900;
+			break;
+		default:
+			*freq = 0;
+			return MV_NOT_SUPPORTED;
+		}
+	}
+
+	return MV_OK;
+}
+
+static int ddr3_tip_a38x_get_medium_freq(int dev_num, enum hws_ddr_freq *freq)
+{
+	u32 reg, ref_clk_satr;
+
+	/* Read sample at reset setting */
+	reg = (reg_read(REG_DEVICE_SAR1_ADDR) >>
+	RST2_CPU_DDR_CLOCK_SELECT_IN_OFFSET) &
+	RST2_CPU_DDR_CLOCK_SELECT_IN_MASK;
+
+	ref_clk_satr = reg_read(DEVICE_SAMPLE_AT_RESET2_REG);
+	if (((ref_clk_satr >> DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_OFFSET) & 0x1) ==
+	    DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_25MHZ) {
+		switch (reg) {
+		case 0x0:
+		case 0x1:
+			/* Medium is same as TF to run PBS in this freq */
+			*freq = DDR_FREQ_333;
+			break;
+		case 0x2:
+		case 0x3:
+			/* Medium is same as TF to run PBS in this freq */
+			*freq = DDR_FREQ_400;
+			break;
+		case 0x4:
+		case 0xd:
+			/* Medium is same as TF to run PBS in this freq */
+			*freq = DDR_FREQ_533;
+			break;
+		case 0x8:
+		case 0x10:
+		case 0x11:
+		case 0x14:
+			*freq = DDR_FREQ_333;
+			break;
+		case 0xc:
+		case 0x15:
+		case 0x1b:
+			*freq = DDR_FREQ_400;
+			break;
+		case 0x6:
+			*freq = DDR_FREQ_300;
+			break;
+		case 0x12:
+			*freq = DDR_FREQ_360;
+			break;
+		case 0x13:
+			*freq = DDR_FREQ_400;
+			break;
+		default:
+			*freq = 0;
+			return MV_NOT_SUPPORTED;
+		}
+	} else { /* REFCLK 40MHz case */
+		switch (reg) {
+		case 0x3:
+			/* Medium is same as TF to run PBS in this freq */
+			*freq = DDR_FREQ_400;
+			break;
+		case 0x5:
+			/* Medium is same as TF to run PBS in this freq */
+			*freq = DDR_FREQ_533;
+			break;
+		case 0xb:
+			*freq = DDR_FREQ_400;
+			break;
+		case 0x1e:
+			*freq = DDR_FREQ_360;
+			break;
+		default:
+			*freq = 0;
+			return MV_NOT_SUPPORTED;
+		}
+	}
+
+	return MV_OK;
+}
+
+static int ddr3_tip_a38x_get_device_info(u8 dev_num, struct ddr3_device_info *info_ptr)
+{
+#if defined(CONFIG_ARMADA_39X)
+	info_ptr->device_id = 0x6900;
+#else
+	info_ptr->device_id = 0x6800;
+#endif
+	info_ptr->ck_delay = ck_delay;
+
+	return MV_OK;
+}
+
+/* check indirect access to phy register file completed */
+static int is_prfa_done(void)
+{
+	u32 reg_val;
+	u32 iter = 0;
+
+	do {
+		if (iter++ > MAX_POLLING_ITERATIONS) {
+			printf("error: %s: polling timeout\n", __func__);
+			return MV_FAIL;
+		}
+		dunit_read(PHY_REG_FILE_ACCESS_REG, MASK_ALL_BITS, &reg_val);
+		reg_val >>= PRFA_REQ_OFFS;
+		reg_val &= PRFA_REQ_MASK;
+	} while (reg_val == PRFA_REQ_ENA); /* request pending */
+
+	return MV_OK;
+}
+
+/* write to phy register thru indirect access */
+static int prfa_write(enum hws_access_type phy_access, u32 phy,
+		      enum hws_ddr_phy phy_type, u32 addr,
+		      u32 data, enum hws_operation op_type)
+{
+	u32 reg_val = ((data & PRFA_DATA_MASK) << PRFA_DATA_OFFS) |
+		      ((addr & PRFA_REG_NUM_MASK) << PRFA_REG_NUM_OFFS) |
+		      ((phy & PRFA_PUP_NUM_MASK) << PRFA_PUP_NUM_OFFS) |
+		      ((phy_type & PRFA_PUP_CTRL_DATA_MASK) << PRFA_PUP_CTRL_DATA_OFFS) |
+		      ((phy_access & PRFA_PUP_BCAST_WR_ENA_MASK) << PRFA_PUP_BCAST_WR_ENA_OFFS) |
+		      (((addr >> 6) & PRFA_REG_NUM_HI_MASK) << PRFA_REG_NUM_HI_OFFS) |
+		      ((op_type & PRFA_TYPE_MASK) << PRFA_TYPE_OFFS);
+	dunit_write(PHY_REG_FILE_ACCESS_REG, MASK_ALL_BITS, reg_val);
+	reg_val |= (PRFA_REQ_ENA << PRFA_REQ_OFFS);
+	dunit_write(PHY_REG_FILE_ACCESS_REG, MASK_ALL_BITS, reg_val);
+
+	/* polling for prfa request completion */
+	if (is_prfa_done() != MV_OK)
+		return MV_FAIL;
+
+	return MV_OK;
+}
+
+/* read from phy register thru indirect access */
+static int prfa_read(enum hws_access_type phy_access, u32 phy,
+		     enum hws_ddr_phy phy_type, u32 addr, u32 *data)
+{
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+	u32 max_phy = ddr3_tip_dev_attr_get(0, MV_ATTR_OCTET_PER_INTERFACE);
+	u32 i, reg_val;
+
+	if (phy_access == ACCESS_TYPE_MULTICAST) {
+		for (i = 0; i < max_phy; i++) {
+			VALIDATE_BUS_ACTIVE(tm->bus_act_mask, i);
+			if (prfa_write(ACCESS_TYPE_UNICAST, i, phy_type, addr, 0, OPERATION_READ) != MV_OK)
+				return MV_FAIL;
+			dunit_read(PHY_REG_FILE_ACCESS_REG, MASK_ALL_BITS, &reg_val);
+			data[i] = (reg_val >> PRFA_DATA_OFFS) & PRFA_DATA_MASK;
+		}
+	} else {
+		if (prfa_write(phy_access, phy, phy_type, addr, 0, OPERATION_READ) != MV_OK)
+			return MV_FAIL;
+		dunit_read(PHY_REG_FILE_ACCESS_REG, MASK_ALL_BITS, &reg_val);
+		*data = (reg_val >> PRFA_DATA_OFFS) & PRFA_DATA_MASK;
+	}
+
+	return MV_OK;
+}
+
+static int mv_ddr_sw_db_init(u32 dev_num, u32 board_id)
+{
+	struct hws_tip_config_func_db config_func;
+
+	/* new read leveling version */
+	config_func.mv_ddr_dunit_read = dunit_read;
+	config_func.mv_ddr_dunit_write = dunit_write;
+	config_func.tip_dunit_mux_select_func =
+		ddr3_tip_a38x_select_ddr_controller;
+	config_func.tip_get_freq_config_info_func =
+		ddr3_tip_a38x_get_freq_config;
+	config_func.tip_set_freq_divider_func = ddr3_tip_a38x_set_divider;
+	config_func.tip_get_device_info_func = ddr3_tip_a38x_get_device_info;
+	config_func.tip_get_temperature = ddr3_ctrl_get_junc_temp;
+	config_func.tip_get_clock_ratio = ddr3_tip_clock_mode;
+	config_func.tip_external_read = ddr3_tip_ext_read;
+	config_func.tip_external_write = ddr3_tip_ext_write;
+	config_func.mv_ddr_phy_read = prfa_read;
+	config_func.mv_ddr_phy_write = prfa_write;
+
+	ddr3_tip_init_config_func(dev_num, &config_func);
+
+	ddr3_tip_register_dq_table(dev_num, dq_bit_map_2_phy_pin);
+
+	/* set device attributes*/
+	ddr3_tip_dev_attr_init(dev_num);
+	ddr3_tip_dev_attr_set(dev_num, MV_ATTR_TIP_REV, MV_TIP_REV_4);
+	ddr3_tip_dev_attr_set(dev_num, MV_ATTR_PHY_EDGE, MV_DDR_PHY_EDGE_POSITIVE);
+	ddr3_tip_dev_attr_set(dev_num, MV_ATTR_OCTET_PER_INTERFACE, DDR_INTERFACE_OCTETS_NUM);
+#ifdef CONFIG_ARMADA_39X
+	ddr3_tip_dev_attr_set(dev_num, MV_ATTR_INTERLEAVE_WA, 1);
+#else
+	ddr3_tip_dev_attr_set(dev_num, MV_ATTR_INTERLEAVE_WA, 0);
+#endif
+
+	ca_delay = 0;
+	delay_enable = 1;
+	dfs_low_freq = DFS_LOW_FREQ_VALUE;
+	calibration_update_control = 1;
+
+#ifdef CONFIG_ARMADA_38X
+	/* For a38x only, change to 2T mode to resolve low freq instability */
+	mode_2t = 1;
+#endif
+
+	ddr3_tip_a38x_get_medium_freq(dev_num, &medium_freq);
+
+	return MV_OK;
+}
+
+static int mv_ddr_training_mask_set(void)
+{
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+	enum hws_ddr_freq ddr_freq = tm->interface_params[0].memory_freq;
+
+	mask_tune_func = (SET_LOW_FREQ_MASK_BIT |
+			  LOAD_PATTERN_MASK_BIT |
+			  SET_MEDIUM_FREQ_MASK_BIT | WRITE_LEVELING_MASK_BIT |
+			  WRITE_LEVELING_SUPP_MASK_BIT |
+			  READ_LEVELING_MASK_BIT |
+			  PBS_RX_MASK_BIT |
+			  PBS_TX_MASK_BIT |
+			  SET_TARGET_FREQ_MASK_BIT |
+			  WRITE_LEVELING_TF_MASK_BIT |
+			  WRITE_LEVELING_SUPP_TF_MASK_BIT |
+			  READ_LEVELING_TF_MASK_BIT |
+			  CENTRALIZATION_RX_MASK_BIT |
+			  CENTRALIZATION_TX_MASK_BIT);
+	rl_mid_freq_wa = 1;
+
+	if ((ddr_freq == DDR_FREQ_333) || (ddr_freq == DDR_FREQ_400)) {
+		mask_tune_func = (WRITE_LEVELING_MASK_BIT |
+				  LOAD_PATTERN_2_MASK_BIT |
+				  WRITE_LEVELING_SUPP_MASK_BIT |
+				  READ_LEVELING_MASK_BIT |
+				  PBS_RX_MASK_BIT |
+				  PBS_TX_MASK_BIT |
+				  CENTRALIZATION_RX_MASK_BIT |
+				  CENTRALIZATION_TX_MASK_BIT);
+		rl_mid_freq_wa = 0; /* WA not needed if 333/400 is TF */
+	}
+
+	/* Supplementary not supported for ECC modes */
+	if (1 == ddr3_if_ecc_enabled()) {
+		mask_tune_func &= ~WRITE_LEVELING_SUPP_TF_MASK_BIT;
+		mask_tune_func &= ~WRITE_LEVELING_SUPP_MASK_BIT;
+		mask_tune_func &= ~PBS_TX_MASK_BIT;
+		mask_tune_func &= ~PBS_RX_MASK_BIT;
+	}
+
+	return MV_OK;
+}
+
+/* function: mv_ddr_set_calib_controller
+ * this function sets the controller which will control
+ * the calibration cycle in the end of the training.
+ * 1 - internal controller
+ * 2 - external controller
+ */
+void mv_ddr_set_calib_controller(void)
+{
+	calibration_update_control = CAL_UPDATE_CTRL_INT;
+}
+
+static int ddr3_tip_a38x_set_divider(u8 dev_num, u32 if_id,
+				     enum hws_ddr_freq frequency)
+{
+	u32 divider = 0;
+	u32 sar_val, ref_clk_satr;
+	u32 async_val;
+
+	if (if_id != 0) {
+		DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR,
+				      ("A38x does not support interface 0x%x\n",
+				       if_id));
+		return MV_BAD_PARAM;
+	}
+
+	/* get VCO freq index */
+	sar_val = (reg_read(REG_DEVICE_SAR1_ADDR) >>
+		   RST2_CPU_DDR_CLOCK_SELECT_IN_OFFSET) &
+		RST2_CPU_DDR_CLOCK_SELECT_IN_MASK;
+
+	ref_clk_satr = reg_read(DEVICE_SAMPLE_AT_RESET2_REG);
+	if (((ref_clk_satr >> DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_OFFSET) & 0x1) ==
+	    DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_25MHZ)
+		divider = a38x_vco_freq_per_sar_ref_clk_25_mhz[sar_val] / freq_val[frequency];
+	else
+		divider = a38x_vco_freq_per_sar_ref_clk_40_mhz[sar_val] / freq_val[frequency];
+
+	if ((async_mode_at_tf == 1) && (freq_val[frequency] > 400)) {
+		/* Set async mode */
+		dunit_write(0x20220, 0x1000, 0x1000);
+		dunit_write(0xe42f4, 0x200, 0x200);
+
+		/* Wait for async mode setup */
+		mdelay(5);
+
+		/* Set KNL values */
+		switch (frequency) {
+#ifdef CONFIG_DDR3
+		case DDR_FREQ_467:
+			async_val = 0x806f012;
+			break;
+		case DDR_FREQ_533:
+			async_val = 0x807f012;
+			break;
+		case DDR_FREQ_600:
+			async_val = 0x805f00a;
+			break;
+#endif
+		case DDR_FREQ_667:
+			async_val = 0x809f012;
+			break;
+		case DDR_FREQ_800:
+			async_val = 0x807f00a;
+			break;
+#ifdef CONFIG_DDR3
+		case DDR_FREQ_850:
+			async_val = 0x80cb012;
+			break;
+#endif
+		case DDR_FREQ_900:
+			async_val = 0x80d7012;
+			break;
+		case DDR_FREQ_933:
+			async_val = 0x80df012;
+			break;
+		case DDR_FREQ_1000:
+			async_val = 0x80ef012;
+			break;
+		case DDR_FREQ_1066:
+			async_val = 0x80ff012;
+			break;
+		default:
+			/* set DDR_FREQ_667 as default */
+			async_val = 0x809f012;
+		}
+		dunit_write(0xe42f0, 0xffffffff, async_val);
+	} else {
+		/* Set sync mode */
+		dunit_write(0x20220, 0x1000, 0x0);
+		dunit_write(0xe42f4, 0x200, 0x0);
+
+		/* cpupll_clkdiv_reset_mask */
+		dunit_write(0xe4264, 0xff, 0x1f);
+
+		/* cpupll_clkdiv_reload_smooth */
+		dunit_write(0xe4260, (0xff << 8), (0x2 << 8));
+
+		/* cpupll_clkdiv_relax_en */
+		dunit_write(0xe4260, (0xff << 24), (0x2 << 24));
+
+		/* write the divider */
+		dunit_write(0xe4268, (0x3f << 8), (divider << 8));
+
+		/* set cpupll_clkdiv_reload_ratio */
+		dunit_write(0xe4264, (1 << 8), (1 << 8));
+
+		/* undet cpupll_clkdiv_reload_ratio */
+		dunit_write(0xe4264, (1 << 8), 0x0);
+
+		/* clear cpupll_clkdiv_reload_force */
+		dunit_write(0xe4260, (0xff << 8), 0x0);
+
+		/* clear cpupll_clkdiv_relax_en */
+		dunit_write(0xe4260, (0xff << 24), 0x0);
+
+		/* clear cpupll_clkdiv_reset_mask */
+		dunit_write(0xe4264, 0xff, 0x0);
+	}
+
+	/* Dunit training clock + 1:1/2:1 mode */
+	dunit_write(0x18488, (1 << 16), ((ddr3_tip_clock_mode(frequency) & 0x1) << 16));
+	dunit_write(0x1524, (1 << 15), ((ddr3_tip_clock_mode(frequency) - 1) << 15));
+
+	return MV_OK;
+}
+
+/*
+ * external read from memory
+ */
+int ddr3_tip_ext_read(u32 dev_num, u32 if_id, u32 reg_addr,
+		      u32 num_of_bursts, u32 *data)
+{
+	u32 burst_num;
+
+	for (burst_num = 0; burst_num < num_of_bursts * 8; burst_num++)
+		data[burst_num] = readl(reg_addr + 4 * burst_num);
+
+	return MV_OK;
+}
+
+/*
+ * external write to memory
+ */
+int ddr3_tip_ext_write(u32 dev_num, u32 if_id, u32 reg_addr,
+		       u32 num_of_bursts, u32 *data) {
+	u32 burst_num;
+
+	for (burst_num = 0; burst_num < num_of_bursts * 8; burst_num++)
+		writel(data[burst_num], reg_addr + 4 * burst_num);
+
+	return MV_OK;
+}
+
+int mv_ddr_early_init(void)
+{
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+
+	/* FIXME: change this configuration per ddr type
+	 * configure a380 and a390 to work with receiver odt timing
+	 * the odt_config is defined:
+	 * '1' in ddr4
+	 * '0' in ddr3
+	 * here the parameter is run over in ddr4 and ddr3 to '1' (in ddr4 the default is '1')
+	 * to configure the odt to work with timing restrictions
+	 */
+
+	mv_ddr_sw_db_init(0, 0);
+
+	if (tm->interface_params[0].memory_freq != DDR_FREQ_SAR)
+		async_mode_at_tf = 1;
+
+	return MV_OK;
+}
+
+int mv_ddr_early_init2(void)
+{
+	mv_ddr_training_mask_set();
+
+	return MV_OK;
+}
+
+int mv_ddr_pre_training_fixup(void)
+{
+	return 0;
+}
+
+int mv_ddr_post_training_fixup(void)
+{
+	return 0;
+}
+
+int ddr3_post_run_alg(void)
+{
+	return MV_OK;
+}
+
+int ddr3_silicon_post_init(void)
+{
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+
+	/* Set half bus width */
+	if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask)) {
+		CHECK_STATUS(ddr3_tip_if_write
+			     (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE,
+			      SDRAM_CFG_REG, 0x0, 0x8000));
+	}
+
+	return MV_OK;
+}
+
+u32 mv_ddr_init_freq_get(void)
+{
+	enum hws_ddr_freq freq;
+
+	mv_ddr_sar_freq_get(0, &freq);
+
+	return freq;
+}
+
+static u32 ddr3_get_bus_width(void)
+{
+	u32 bus_width;
+
+	bus_width = (reg_read(SDRAM_CFG_REG) & 0x8000) >>
+		BUS_IN_USE_OFFS;
+
+	return (bus_width == 0) ? 16 : 32;
+}
+
+static u32 ddr3_get_device_width(u32 cs)
+{
+	u32 device_width;
+
+	device_width = (reg_read(SDRAM_ADDR_CTRL_REG) &
+			(CS_STRUCT_MASK << CS_STRUCT_OFFS(cs))) >>
+			CS_STRUCT_OFFS(cs);
+
+	return (device_width == 0) ? 8 : 16;
+}
+
+static u32 ddr3_get_device_size(u32 cs)
+{
+	u32 device_size_low, device_size_high, device_size;
+	u32 data, cs_low_offset, cs_high_offset;
+
+	cs_low_offset = CS_SIZE_OFFS(cs);
+	cs_high_offset = CS_SIZE_HIGH_OFFS(cs);
+
+	data = reg_read(SDRAM_ADDR_CTRL_REG);
+	device_size_low = (data >> cs_low_offset) & 0x3;
+	device_size_high = (data >> cs_high_offset) & 0x1;
+
+	device_size = device_size_low | (device_size_high << 2);
+
+	switch (device_size) {
+	case 0:
+		return 2048;
+	case 2:
+		return 512;
+	case 3:
+		return 1024;
+	case 4:
+		return 4096;
+	case 5:
+		return 8192;
+	case 1:
+	default:
+		DEBUG_INIT_C("Error: Wrong device size of Cs: ", cs, 1);
+		/* zeroes mem size in ddr3_calc_mem_cs_size */
+		return 0;
+	}
+}
+
+static int ddr3_calc_mem_cs_size(u32 cs, uint64_t *cs_size)
+{
+	u32 cs_mem_size;
+
+	/* Calculate in MiB */
+	cs_mem_size = ((ddr3_get_bus_width() / ddr3_get_device_width(cs)) *
+		       ddr3_get_device_size(cs)) / 8;
+
+	/*
+	 * Multiple controller bus width, 2x for 64 bit
+	 * (SoC controller may be 32 or 64 bit,
+	 * so bit 15 in 0x1400, that means if whole bus used or only half,
+	 * have a differnt meaning
+	 */
+	cs_mem_size *= DDR_CONTROLLER_BUS_WIDTH_MULTIPLIER;
+
+	if ((cs_mem_size < 128) || (cs_mem_size > 4096)) {
+		DEBUG_INIT_C("Error: Wrong Memory size of Cs: ", cs, 1);
+		return MV_BAD_VALUE;
+	}
+
+	*cs_size = cs_mem_size << 20; /* write cs size in bytes */
+
+	return MV_OK;
+}
+
+static int ddr3_fast_path_dynamic_cs_size_config(u32 cs_ena)
+{
+	u32 reg, cs;
+	uint64_t mem_total_size = 0;
+	uint64_t cs_mem_size = 0;
+	uint64_t mem_total_size_c, cs_mem_size_c;
+
+#ifdef DEVICE_MAX_DRAM_ADDRESS_SIZE
+	u32 physical_mem_size;
+	u32 max_mem_size = DEVICE_MAX_DRAM_ADDRESS_SIZE;
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+#endif
+
+	/* Open fast path windows */
+	for (cs = 0; cs < MAX_CS_NUM; cs++) {
+		if (cs_ena & (1 << cs)) {
+			/* get CS size */
+			if (ddr3_calc_mem_cs_size(cs, &cs_mem_size) != MV_OK)
+				return MV_FAIL;
+
+#ifdef DEVICE_MAX_DRAM_ADDRESS_SIZE
+			/*
+			 * if number of address pins doesn't allow to use max
+			 * mem size that is defined in topology
+			 * mem size is defined by DEVICE_MAX_DRAM_ADDRESS_SIZE
+			 */
+			physical_mem_size = mem_size
+				[tm->interface_params[0].memory_size];
+
+			if (ddr3_get_device_width(cs) == 16) {
+				/*
+				 * 16bit mem device can be twice more - no need
+				 * in less significant pin
+				 */
+				max_mem_size = DEVICE_MAX_DRAM_ADDRESS_SIZE * 2;
+			}
+
+			if (physical_mem_size > max_mem_size) {
+				cs_mem_size = max_mem_size *
+					(ddr3_get_bus_width() /
+					 ddr3_get_device_width(cs));
+				printf("Updated Physical Mem size is from 0x%x to %x\n",
+				       physical_mem_size,
+				       DEVICE_MAX_DRAM_ADDRESS_SIZE);
+			}
+#endif
+
+			/* set fast path window control for the cs */
+			reg = 0xffffe1;
+			reg |= (cs << 2);
+			reg |= (cs_mem_size - 1) & 0xffff0000;
+			/*Open fast path Window */
+			reg_write(REG_FASTPATH_WIN_CTRL_ADDR(cs), reg);
+
+			/* Set fast path window base address for the cs */
+			reg = ((cs_mem_size) * cs) & 0xffff0000;
+			/* Set base address */
+			reg_write(REG_FASTPATH_WIN_BASE_ADDR(cs), reg);
+
+			/*
+			 * Since memory size may be bigger than 4G the summ may
+			 * be more than 32 bit word,
+			 * so to estimate the result divide mem_total_size and
+			 * cs_mem_size by 0x10000 (it is equal to >> 16)
+			 */
+			mem_total_size_c = (mem_total_size >> 16) & 0xffffffffffff;
+			cs_mem_size_c = (cs_mem_size >> 16) & 0xffffffffffff;
+			/* if the sum less than 2 G - calculate the value */
+			if (mem_total_size_c + cs_mem_size_c < 0x10000)
+				mem_total_size += cs_mem_size;
+			else	/* put max possible size */
+				mem_total_size = L2_FILTER_FOR_MAX_MEMORY_SIZE;
+		}
+	}
+
+	/* Set L2 filtering to Max Memory size */
+	reg_write(ADDRESS_FILTERING_END_REGISTER, mem_total_size);
+
+	return MV_OK;
+}
+
+static int ddr3_restore_and_set_final_windows(u32 *win, const char *ddr_type)
+{
+	u32 win_ctrl_reg, num_of_win_regs;
+	u32 cs_ena = mv_ddr_sys_env_get_cs_ena_from_reg();
+	u32 ui;
+
+	win_ctrl_reg = REG_XBAR_WIN_4_CTRL_ADDR;
+	num_of_win_regs = 16;
+
+	/* Return XBAR windows 4-7 or 16-19 init configuration */
+	for (ui = 0; ui < num_of_win_regs; ui++)
+		reg_write((win_ctrl_reg + 0x4 * ui), win[ui]);
+
+	printf("%s Training Sequence - Switching XBAR Window to FastPath Window\n",
+	       ddr_type);
+
+#if defined DYNAMIC_CS_SIZE_CONFIG
+	if (ddr3_fast_path_dynamic_cs_size_config(cs_ena) != MV_OK)
+		printf("ddr3_fast_path_dynamic_cs_size_config FAILED\n");
+#else
+	u32 reg, cs;
+	reg = 0x1fffffe1;
+	for (cs = 0; cs < MAX_CS_NUM; cs++) {
+		if (cs_ena & (1 << cs)) {
+			reg |= (cs << 2);
+			break;
+		}
+	}
+	/* Open fast path Window to - 0.5G */
+	reg_write(REG_FASTPATH_WIN_CTRL_ADDR(0), reg);
+#endif
+
+	return MV_OK;
+}
+
+static int ddr3_save_and_set_training_windows(u32 *win)
+{
+	u32 cs_ena;
+	u32 reg, tmp_count, cs, ui;
+	u32 win_ctrl_reg, win_base_reg, win_remap_reg;
+	u32 num_of_win_regs, win_jump_index;
+	win_ctrl_reg = REG_XBAR_WIN_4_CTRL_ADDR;
+	win_base_reg = REG_XBAR_WIN_4_BASE_ADDR;
+	win_remap_reg = REG_XBAR_WIN_4_REMAP_ADDR;
+	win_jump_index = 0x10;
+	num_of_win_regs = 16;
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+
+#ifdef DISABLE_L2_FILTERING_DURING_DDR_TRAINING
+	/*
+	 * Disable L2 filtering during DDR training
+	 * (when Cross Bar window is open)
+	 */
+	reg_write(ADDRESS_FILTERING_END_REGISTER, 0);
+#endif
+
+	cs_ena = tm->interface_params[0].as_bus_params[0].cs_bitmask;
+
+	/* Close XBAR Window 19 - Not needed */
+	/* {0x000200e8}  -   Open Mbus Window - 2G */
+	reg_write(REG_XBAR_WIN_19_CTRL_ADDR, 0);
+
+	/* Save XBAR Windows 4-19 init configurations */
+	for (ui = 0; ui < num_of_win_regs; ui++)
+		win[ui] = reg_read(win_ctrl_reg + 0x4 * ui);
+
+	/* Open XBAR Windows 4-7 or 16-19 for other CS */
+	reg = 0;
+	tmp_count = 0;
+	for (cs = 0; cs < MAX_CS_NUM; cs++) {
+		if (cs_ena & (1 << cs)) {
+			switch (cs) {
+			case 0:
+				reg = 0x0e00;
+				break;
+			case 1:
+				reg = 0x0d00;
+				break;
+			case 2:
+				reg = 0x0b00;
+				break;
+			case 3:
+				reg = 0x0700;
+				break;
+			}
+			reg |= (1 << 0);
+			reg |= (SDRAM_CS_SIZE & 0xffff0000);
+
+			reg_write(win_ctrl_reg + win_jump_index * tmp_count,
+				  reg);
+			reg = (((SDRAM_CS_SIZE + 1) * (tmp_count)) &
+			       0xffff0000);
+			reg_write(win_base_reg + win_jump_index * tmp_count,
+				  reg);
+
+			if (win_remap_reg <= REG_XBAR_WIN_7_REMAP_ADDR)
+				reg_write(win_remap_reg +
+					  win_jump_index * tmp_count, 0);
+
+			tmp_count++;
+		}
+	}
+
+	return MV_OK;
+}
+
+static u32 win[16];
+
+int mv_ddr_pre_training_soc_config(const char *ddr_type)
+{
+	u32 soc_num;
+	u32 reg_val;
+
+	/* Switching CPU to MRVL ID */
+	soc_num = (reg_read(REG_SAMPLE_RESET_HIGH_ADDR) & SAR1_CPU_CORE_MASK) >>
+		SAR1_CPU_CORE_OFFSET;
+	switch (soc_num) {
+	case 0x3:
+		reg_bit_set(CPU_CONFIGURATION_REG(3), CPU_MRVL_ID_OFFSET);
+		reg_bit_set(CPU_CONFIGURATION_REG(2), CPU_MRVL_ID_OFFSET);
+		/* fallthrough */
+	case 0x1:
+		reg_bit_set(CPU_CONFIGURATION_REG(1), CPU_MRVL_ID_OFFSET);
+		/* fallthrough */
+	case 0x0:
+		reg_bit_set(CPU_CONFIGURATION_REG(0), CPU_MRVL_ID_OFFSET);
+		/* fallthrough */
+	default:
+		break;
+	}
+
+	/*
+	 * Set DRAM Reset Mask in case detected GPIO indication of wakeup from
+	 * suspend i.e the DRAM values will not be overwritten / reset when
+	 * waking from suspend
+	 */
+	if (mv_ddr_sys_env_suspend_wakeup_check() ==
+	    SUSPEND_WAKEUP_ENABLED_GPIO_DETECTED) {
+		reg_bit_set(SDRAM_INIT_CTRL_REG,
+			    DRAM_RESET_MASK_MASKED << DRAM_RESET_MASK_OFFS);
+	}
+
+	/* Check if DRAM is already initialized  */
+	if (reg_read(REG_BOOTROM_ROUTINE_ADDR) &
+	    (1 << REG_BOOTROM_ROUTINE_DRAM_INIT_OFFS)) {
+		printf("%s Training Sequence - 2nd boot - Skip\n", ddr_type);
+		return MV_OK;
+	}
+
+	/* Fix read ready phases for all SOC in reg 0x15c8 */
+	reg_val = reg_read(TRAINING_DBG_3_REG);
+
+	reg_val &= ~(TRN_DBG_RDY_INC_PH_2TO1_MASK << TRN_DBG_RDY_INC_PH_2TO1_OFFS(0));
+	reg_val |= (0x4 << TRN_DBG_RDY_INC_PH_2TO1_OFFS(0));	/* phase 0 */
+
+	reg_val &= ~(TRN_DBG_RDY_INC_PH_2TO1_MASK << TRN_DBG_RDY_INC_PH_2TO1_OFFS(1));
+	reg_val |= (0x4 << TRN_DBG_RDY_INC_PH_2TO1_OFFS(1));	/* phase 1 */
+
+	reg_val &= ~(TRN_DBG_RDY_INC_PH_2TO1_MASK << TRN_DBG_RDY_INC_PH_2TO1_OFFS(3));
+	reg_val |= (0x6 << TRN_DBG_RDY_INC_PH_2TO1_OFFS(3));	/* phase 3 */
+
+	reg_val &= ~(TRN_DBG_RDY_INC_PH_2TO1_MASK << TRN_DBG_RDY_INC_PH_2TO1_OFFS(4));
+	reg_val |= (0x6 << TRN_DBG_RDY_INC_PH_2TO1_OFFS(4));	/* phase 4 */
+
+	reg_val &= ~(TRN_DBG_RDY_INC_PH_2TO1_MASK << TRN_DBG_RDY_INC_PH_2TO1_OFFS(5));
+	reg_val |= (0x6 << TRN_DBG_RDY_INC_PH_2TO1_OFFS(5));	/* phase 5 */
+
+	reg_write(TRAINING_DBG_3_REG, reg_val);
+
+	/*
+	 * Axi_bresp_mode[8] = Compliant,
+	 * Axi_addr_decode_cntrl[11] = Internal,
+	 * Axi_data_bus_width[0] = 128bit
+	 * */
+	/* 0x14a8 - AXI Control Register */
+	reg_write(AXI_CTRL_REG, 0);
+
+	/*
+	 * Stage 2 - Training Values Setup
+	 */
+	/* Set X-BAR windows for the training sequence */
+	ddr3_save_and_set_training_windows(win);
+
+	return MV_OK;
+}
+
+static int ddr3_new_tip_dlb_config(void)
+{
+	u32 reg, i = 0;
+	struct dlb_config *config_table_ptr = sys_env_dlb_config_ptr_get();
+
+	/* Write the configuration */
+	while (config_table_ptr[i].reg_addr != 0) {
+		reg_write(config_table_ptr[i].reg_addr,
+			  config_table_ptr[i].reg_data);
+		i++;
+	}
+
+
+	/* Enable DLB */
+	reg = reg_read(DLB_CTRL_REG);
+	reg &= ~(DLB_EN_MASK << DLB_EN_OFFS) &
+	       ~(WR_COALESCE_EN_MASK << WR_COALESCE_EN_OFFS) &
+	       ~(AXI_PREFETCH_EN_MASK << AXI_PREFETCH_EN_OFFS) &
+	       ~(MBUS_PREFETCH_EN_MASK << MBUS_PREFETCH_EN_OFFS) &
+	       ~(PREFETCH_NXT_LN_SZ_TRIG_MASK << PREFETCH_NXT_LN_SZ_TRIG_OFFS);
+
+	reg |= (DLB_EN_ENA << DLB_EN_OFFS) |
+	       (WR_COALESCE_EN_ENA << WR_COALESCE_EN_OFFS) |
+	       (AXI_PREFETCH_EN_ENA << AXI_PREFETCH_EN_OFFS) |
+	       (MBUS_PREFETCH_EN_ENA << MBUS_PREFETCH_EN_OFFS) |
+	       (PREFETCH_NXT_LN_SZ_TRIG_ENA << PREFETCH_NXT_LN_SZ_TRIG_OFFS);
+
+	reg_write(DLB_CTRL_REG, reg);
+
+	return MV_OK;
+}
+
+int mv_ddr_post_training_soc_config(const char *ddr_type)
+{
+	u32 reg_val;
+
+	/* Restore and set windows */
+	ddr3_restore_and_set_final_windows(win, ddr_type);
+
+	/* Update DRAM init indication in bootROM register */
+	reg_val = reg_read(REG_BOOTROM_ROUTINE_ADDR);
+	reg_write(REG_BOOTROM_ROUTINE_ADDR,
+		  reg_val | (1 << REG_BOOTROM_ROUTINE_DRAM_INIT_OFFS));
+
+	/* DLB config */
+	ddr3_new_tip_dlb_config();
+
+	return MV_OK;
+}
+
+void mv_ddr_mc_config(void)
+{
+	/* Memory controller initializations */
+	struct init_cntr_param init_param;
+	int status;
+
+	init_param.do_mrs_phy = 1;
+	init_param.is_ctrl64_bit = 0;
+	init_param.init_phy = 1;
+	init_param.msys_init = 1;
+	status = hws_ddr3_tip_init_controller(0, &init_param);
+	if (status != MV_OK)
+		printf("DDR3 init controller - FAILED 0x%x\n", status);
+
+	status = mv_ddr_mc_init();
+	if (status != MV_OK)
+		printf("DDR3 init_sequence - FAILED 0x%x\n", status);
+}
+/* function: mv_ddr_mc_init
+ * this function enables the dunit after init controller configuration
+ */
+int mv_ddr_mc_init(void)
+{
+	CHECK_STATUS(ddr3_tip_enable_init_sequence(0));
+
+	return MV_OK;
+}
+
+/* function: ddr3_tip_configure_phy
+ * configures phy and electrical parameters
+ */
+int ddr3_tip_configure_phy(u32 dev_num)
+{
+	u32 if_id, phy_id;
+	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+
+	CHECK_STATUS(ddr3_tip_bus_write
+		(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+		ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA,
+		PAD_ZRI_CAL_PHY_REG,
+		((0x7f & g_zpri_data) << 7 | (0x7f & g_znri_data))));
+	CHECK_STATUS(ddr3_tip_bus_write
+		(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+		ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL,
+		PAD_ZRI_CAL_PHY_REG,
+		((0x7f & g_zpri_ctrl) << 7 | (0x7f & g_znri_ctrl))));
+	CHECK_STATUS(ddr3_tip_bus_write
+		(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+		ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA,
+		PAD_ODT_CAL_PHY_REG,
+		((0x3f & g_zpodt_data) << 6 | (0x3f & g_znodt_data))));
+	CHECK_STATUS(ddr3_tip_bus_write
+		(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+		ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL,
+		PAD_ODT_CAL_PHY_REG,
+		((0x3f & g_zpodt_ctrl) << 6 | (0x3f & g_znodt_ctrl))));
+
+	CHECK_STATUS(ddr3_tip_bus_write
+		(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+		ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA,
+		PAD_PRE_DISABLE_PHY_REG, 0));
+	CHECK_STATUS(ddr3_tip_bus_write
+		(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+		ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA,
+		CMOS_CONFIG_PHY_REG, 0));
+	CHECK_STATUS(ddr3_tip_bus_write
+		(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+		ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL,
+		CMOS_CONFIG_PHY_REG, 0));
+
+	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+		/* check if the interface is enabled */
+		VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
+
+		for (phy_id = 0;
+			phy_id < octets_per_if_num;
+			phy_id++) {
+				VALIDATE_BUS_ACTIVE(tm->bus_act_mask, phy_id);
+				/* Vref & clamp */
+				CHECK_STATUS(ddr3_tip_bus_read_modify_write
+					(dev_num, ACCESS_TYPE_UNICAST,
+					if_id, phy_id, DDR_PHY_DATA,
+					PAD_CFG_PHY_REG,
+					((clamp_tbl[if_id] << 4) | vref_init_val),
+					((0x7 << 4) | 0x7)));
+				/* clamp not relevant for control */
+				CHECK_STATUS(ddr3_tip_bus_read_modify_write
+					(dev_num, ACCESS_TYPE_UNICAST,
+					if_id, phy_id, DDR_PHY_CONTROL,
+					PAD_CFG_PHY_REG, 0x4, 0x7));
+		}
+	}
+
+	if (ddr3_tip_dev_attr_get(dev_num, MV_ATTR_PHY_EDGE) ==
+		MV_DDR_PHY_EDGE_POSITIVE)
+		CHECK_STATUS(ddr3_tip_bus_write
+		(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+		ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+		DDR_PHY_DATA, 0x90, 0x6002));
+
+
+	return MV_OK;
+}
+
+
+int mv_ddr_manual_cal_do(void)
+{
+	return 0;
+}
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_plat.h b/drivers/ddr/marvell/a38x/mv_ddr_plat.h
new file mode 100644
index 000000000000..73e54c4b735c
--- /dev/null
+++ b/drivers/ddr/marvell/a38x/mv_ddr_plat.h
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#ifndef _MV_DDR_PLAT_H
+#define _MV_DDR_PLAT_H
+
+#define MAX_INTERFACE_NUM		1
+#define MAX_BUS_NUM			5
+#define DDR_IF_CTRL_SUBPHYS_NUM		3
+
+#define DFS_LOW_FREQ_VALUE		120
+#define SDRAM_CS_SIZE			0xfffffff	/* FIXME: implement a function for cs size for each platform */
+
+#define INTER_REGS_BASE			SOC_REGS_PHY_BASE
+#define AP_INT_REG_START_ADDR		0xd0000000
+#define AP_INT_REG_END_ADDR		0xd0100000
+
+/* Controler bus divider 1 for 32 bit, 2 for 64 bit */
+#define DDR_CONTROLLER_BUS_WIDTH_MULTIPLIER	1
+
+/* Tune internal training params values */
+#define TUNE_TRAINING_PARAMS_CK_DELAY		160
+#define TUNE_TRAINING_PARAMS_PHYREG3VAL		0xA
+#define TUNE_TRAINING_PARAMS_PRI_DATA		123
+#define TUNE_TRAINING_PARAMS_NRI_DATA		123
+#define TUNE_TRAINING_PARAMS_PRI_CTRL		74
+#define TUNE_TRAINING_PARAMS_NRI_CTRL		74
+#define TUNE_TRAINING_PARAMS_P_ODT_DATA		45
+#define TUNE_TRAINING_PARAMS_N_ODT_DATA		45
+#define TUNE_TRAINING_PARAMS_P_ODT_CTRL		45
+#define TUNE_TRAINING_PARAMS_N_ODT_CTRL		45
+#define TUNE_TRAINING_PARAMS_DIC		0x2
+#define TUNE_TRAINING_PARAMS_ODT_CONFIG_2CS	0x120012
+#define TUNE_TRAINING_PARAMS_ODT_CONFIG_1CS	0x10000
+#define TUNE_TRAINING_PARAMS_RTT_NOM		0x44
+
+#define TUNE_TRAINING_PARAMS_RTT_WR_1CS		0x0   /*off*/
+#define TUNE_TRAINING_PARAMS_RTT_WR_2CS		0x0   /*off*/
+
+#define MARVELL_BOARD				MARVELL_BOARD_ID_BASE
+
+
+#define REG_DEVICE_SAR1_ADDR			0xe4204
+#define RST2_CPU_DDR_CLOCK_SELECT_IN_OFFSET	17
+#define RST2_CPU_DDR_CLOCK_SELECT_IN_MASK	0x1f
+#define DEVICE_SAMPLE_AT_RESET2_REG		0x18604
+
+#define DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_OFFSET	0
+#define DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_25MHZ	0
+#define DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_40MHZ	1
+
+/* DRAM Windows */
+#define REG_XBAR_WIN_5_CTRL_ADDR		0x20050
+#define REG_XBAR_WIN_5_BASE_ADDR		0x20054
+
+/* DRAM Windows */
+#define REG_XBAR_WIN_4_CTRL_ADDR                0x20040
+#define REG_XBAR_WIN_4_BASE_ADDR                0x20044
+#define REG_XBAR_WIN_4_REMAP_ADDR               0x20048
+#define REG_XBAR_WIN_7_REMAP_ADDR               0x20078
+#define REG_XBAR_WIN_16_CTRL_ADDR               0x200d0
+#define REG_XBAR_WIN_16_BASE_ADDR               0x200d4
+#define REG_XBAR_WIN_16_REMAP_ADDR              0x200dc
+#define REG_XBAR_WIN_19_CTRL_ADDR               0x200e8
+
+#define REG_FASTPATH_WIN_BASE_ADDR(win)         (0x20180 + (0x8 * win))
+#define REG_FASTPATH_WIN_CTRL_ADDR(win)         (0x20184 + (0x8 * win))
+
+#define CPU_CONFIGURATION_REG(id)	(0x21800 + (id * 0x100))
+#define CPU_MRVL_ID_OFFSET		0x10
+#define SAR1_CPU_CORE_MASK		0x00000018
+#define SAR1_CPU_CORE_OFFSET		3
+
+/* SatR defined too change topology busWidth and ECC configuration */
+#define DDR_SATR_CONFIG_MASK_WIDTH		0x8
+#define DDR_SATR_CONFIG_MASK_ECC		0x10
+#define DDR_SATR_CONFIG_MASK_ECC_PUP		0x20
+
+#define	REG_SAMPLE_RESET_HIGH_ADDR		0x18600
+
+#define MV_BOARD_REFCLK_25MHZ			25000000
+#define MV_BOARD_REFCLK				MV_BOARD_REFCLK_25MHZ
+
+#define MAX_DQ_NUM				40
+
+/* dram line buffer registers */
+#define DLB_CTRL_REG			0x1700
+#define DLB_EN_OFFS			0
+#define DLB_EN_MASK			0x1
+#define DLB_EN_ENA			1
+#define DLB_EN_DIS			0
+#define WR_COALESCE_EN_OFFS		2
+#define WR_COALESCE_EN_MASK		0x1
+#define WR_COALESCE_EN_ENA		1
+#define WR_COALESCE_EN_DIS		0
+#define AXI_PREFETCH_EN_OFFS		3
+#define AXI_PREFETCH_EN_MASK		0x1
+#define AXI_PREFETCH_EN_ENA		1
+#define AXI_PREFETCH_EN_DIS		0
+#define MBUS_PREFETCH_EN_OFFS		4
+#define MBUS_PREFETCH_EN_MASK		0x1
+#define MBUS_PREFETCH_EN_ENA		1
+#define MBUS_PREFETCH_EN_DIS		0
+#define PREFETCH_NXT_LN_SZ_TRIG_OFFS	6
+#define PREFETCH_NXT_LN_SZ_TRIG_MASK	0x1
+#define PREFETCH_NXT_LN_SZ_TRIG_ENA	1
+#define PREFETCH_NXT_LN_SZ_TRIG_DIS	0
+
+#define DLB_BUS_OPT_WT_REG		0x1704
+#define DLB_AGING_REG			0x1708
+#define DLB_EVICTION_CTRL_REG		0x170c
+#define DLB_EVICTION_TIMERS_REG		0x1710
+#define DLB_USER_CMD_REG		0x1714
+#define DLB_WTS_DIFF_CS_REG		0x1770
+#define DLB_WTS_DIFF_BG_REG		0x1774
+#define DLB_WTS_SAME_BG_REG		0x1778
+#define DLB_WTS_CMDS_REG		0x177c
+#define DLB_WTS_ATTR_PRIO_REG		0x1780
+#define DLB_QUEUE_MAP_REG		0x1784
+#define DLB_SPLIT_REG			0x1788
+
+/* Subphy result control per byte registers */
+#define RESULT_CONTROL_BYTE_PUP_0_REG		0x1830
+#define RESULT_CONTROL_BYTE_PUP_1_REG		0x1834
+#define RESULT_CONTROL_BYTE_PUP_2_REG		0x1838
+#define RESULT_CONTROL_BYTE_PUP_3_REG		0x183c
+#define RESULT_CONTROL_BYTE_PUP_4_REG		0x18b0
+
+/* Subphy result control per bit registers */
+#define RESULT_CONTROL_PUP_0_BIT_0_REG		0x18b4
+#define RESULT_CONTROL_PUP_0_BIT_1_REG		0x18b8
+#define RESULT_CONTROL_PUP_0_BIT_2_REG		0x18bc
+#define RESULT_CONTROL_PUP_0_BIT_3_REG		0x18c0
+#define RESULT_CONTROL_PUP_0_BIT_4_REG		0x18c4
+#define RESULT_CONTROL_PUP_0_BIT_5_REG		0x18c8
+#define RESULT_CONTROL_PUP_0_BIT_6_REG		0x18cc
+#define RESULT_CONTROL_PUP_0_BIT_7_REG		0x18f0
+
+#define RESULT_CONTROL_PUP_1_BIT_0_REG		0x18f4
+#define RESULT_CONTROL_PUP_1_BIT_1_REG		0x18f8
+#define RESULT_CONTROL_PUP_1_BIT_2_REG		0x18fc
+#define RESULT_CONTROL_PUP_1_BIT_3_REG		0x1930
+#define RESULT_CONTROL_PUP_1_BIT_4_REG		0x1934
+#define RESULT_CONTROL_PUP_1_BIT_5_REG		0x1938
+#define RESULT_CONTROL_PUP_1_BIT_6_REG		0x193c
+#define RESULT_CONTROL_PUP_1_BIT_7_REG		0x19b0
+
+#define RESULT_CONTROL_PUP_2_BIT_0_REG		0x19b4
+#define RESULT_CONTROL_PUP_2_BIT_1_REG		0x19b8
+#define RESULT_CONTROL_PUP_2_BIT_2_REG		0x19bc
+#define RESULT_CONTROL_PUP_2_BIT_3_REG		0x19c0
+#define RESULT_CONTROL_PUP_2_BIT_4_REG		0x19c4
+#define RESULT_CONTROL_PUP_2_BIT_5_REG		0x19c8
+#define RESULT_CONTROL_PUP_2_BIT_6_REG		0x19cc
+#define RESULT_CONTROL_PUP_2_BIT_7_REG		0x19f0
+
+#define RESULT_CONTROL_PUP_3_BIT_0_REG		0x19f4
+#define RESULT_CONTROL_PUP_3_BIT_1_REG		0x19f8
+#define RESULT_CONTROL_PUP_3_BIT_2_REG		0x19fc
+#define RESULT_CONTROL_PUP_3_BIT_3_REG		0x1a30
+#define RESULT_CONTROL_PUP_3_BIT_4_REG		0x1a34
+#define RESULT_CONTROL_PUP_3_BIT_5_REG		0x1a38
+#define RESULT_CONTROL_PUP_3_BIT_6_REG		0x1a3c
+#define RESULT_CONTROL_PUP_3_BIT_7_REG		0x1ab0
+
+#define RESULT_CONTROL_PUP_4_BIT_0_REG		0x1ab4
+#define RESULT_CONTROL_PUP_4_BIT_1_REG		0x1ab8
+#define RESULT_CONTROL_PUP_4_BIT_2_REG		0x1abc
+#define RESULT_CONTROL_PUP_4_BIT_3_REG		0x1ac0
+#define RESULT_CONTROL_PUP_4_BIT_4_REG		0x1ac4
+#define RESULT_CONTROL_PUP_4_BIT_5_REG		0x1ac8
+#define RESULT_CONTROL_PUP_4_BIT_6_REG		0x1acc
+#define RESULT_CONTROL_PUP_4_BIT_7_REG		0x1af0
+
+/* CPU */
+#define REG_BOOTROM_ROUTINE_ADDR		0x182d0
+#define REG_BOOTROM_ROUTINE_DRAM_INIT_OFFS	12
+
+/* Matrix enables DRAM modes (bus width/ECC) per boardId */
+#define TOPOLOGY_UPDATE_32BIT			0
+#define TOPOLOGY_UPDATE_32BIT_ECC		1
+#define TOPOLOGY_UPDATE_16BIT			2
+#define TOPOLOGY_UPDATE_16BIT_ECC		3
+#define TOPOLOGY_UPDATE_16BIT_ECC_PUP3		4
+#define TOPOLOGY_UPDATE { \
+		/* 32Bit, 32bit ECC, 16bit, 16bit ECC PUP4, 16bit ECC PUP3 */ \
+		{1, 1, 1, 1, 1},	/* RD_NAS_68XX_ID */ \
+		{1, 1, 1, 1, 1},	/* DB_68XX_ID	  */ \
+		{1, 0, 1, 0, 1},	/* RD_AP_68XX_ID  */ \
+		{1, 0, 1, 0, 1},	/* DB_AP_68XX_ID  */ \
+		{1, 0, 1, 0, 1},	/* DB_GP_68XX_ID  */ \
+		{0, 0, 1, 1, 0},	/* DB_BP_6821_ID  */ \
+		{1, 1, 1, 1, 1}		/* DB_AMC_6820_ID */ \
+	};
+
+enum {
+	CPU_1066MHZ_DDR_400MHZ,
+	CPU_RESERVED_DDR_RESERVED0,
+	CPU_667MHZ_DDR_667MHZ,
+	CPU_800MHZ_DDR_800MHZ,
+	CPU_RESERVED_DDR_RESERVED1,
+	CPU_RESERVED_DDR_RESERVED2,
+	CPU_RESERVED_DDR_RESERVED3,
+	LAST_FREQ
+};
+
+/* struct used for DLB configuration array */
+struct dlb_config {
+	u32 reg_addr;
+	u32 reg_data;
+};
+
+#define ACTIVE_INTERFACE_MASK			0x1
+
+extern u32 dmin_phy_reg_table[][2];
+extern u16 odt_slope[];
+extern u16 odt_intercept[];
+
+int mv_ddr_pre_training_soc_config(const char *ddr_type);
+int mv_ddr_post_training_soc_config(const char *ddr_type);
+void mv_ddr_mem_scrubbing(void);
+
+void mv_ddr_odpg_enable(void);
+void mv_ddr_odpg_disable(void);
+void mv_ddr_odpg_done_clr(void);
+int mv_ddr_is_odpg_done(u32 count);
+void mv_ddr_training_enable(void);
+int mv_ddr_is_training_done(u32 count, u32 *result);
+u32 mv_ddr_dm_pad_get(void);
+int mv_ddr_pre_training_fixup(void);
+int mv_ddr_post_training_fixup(void);
+int mv_ddr_manual_cal_do(void);
+#endif /* _MV_DDR_PLAT_H */
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_regs.h b/drivers/ddr/marvell/a38x/mv_ddr_regs.h
new file mode 100644
index 000000000000..0fc5541e801c
--- /dev/null
+++ b/drivers/ddr/marvell/a38x/mv_ddr_regs.h
@@ -0,0 +1,447 @@
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#ifndef _MV_DDR_REGS_H
+#define _MV_DDR_REGS_H
+
+#define GLOB_CTRL_STATUS_REG			0x1030
+#define TRAINING_TRIGGER_OFFS			0
+#define TRAINING_TRIGGER_MASK			0x1
+#define TRAINING_TRIGGER_ENA			1
+#define TRAINING_DONE_OFFS			1
+#define TRAINING_DONE_MASK			0x1
+#define TRAINING_DONE_DONE			1
+#define TRAINING_DONE_NOT_DONE			0
+#define TRAINING_RESULT_OFFS			2
+#define TRAINING_RESULT_MASK			0x1
+#define TRAINING_RESULT_PASS			0
+#define TRAINING_RESULT_FAIL			1
+
+#define GENERAL_TRAINING_OPCODE_REG		0x1034
+
+#define OPCODE_REG0_BASE			0x1038
+#define OPCODE_REG0_REG(obj)			(OPCODE_REG0_BASE + (obj) * 0x4)
+
+#define OPCODE_REG1_BASE			0x10b0
+#define OPCODE_REG1_REG(obj)			(OPCODE_REG1_BASE + (obj) * 0x4)
+
+#define CAL_PHY_BASE				0x10c0
+#define CAL_PHY_REG(obj)			(CAL_PHY_BASE + (obj) * 0x4)
+
+#define WL_DONE_CNTR_REF_REG			0x10f8
+#define ODPG_WR_RD_MODE_ENA_REG			0x10fc
+
+#define SDRAM_CFG_REG				0x1400
+#define REFRESH_OFFS				0
+#define REFRESH_MASK				0x3fff
+#define DRAM_TYPE_OFFS				14
+#define DRAM_TYPE_MASK				0x1
+#define BUS_IN_USE_OFFS				15
+#define BUS_IN_USE_MASK				0x1
+#define CPU_2DRAM_WR_BUFF_CUT_TH_OFFS		16
+#define CPU_2DRAM_WR_BUFF_CUT_TH_MASK		0x1
+#define REG_DIMM_OFFS				17
+#define REG_DIMM_MASK				0x1
+#define ECC_OFFS				18
+#define ECC_MASK				0x1
+#define IGNORE_ERRORS_OFFS			19
+#define IGNORE_ERRORS_MASK			0x1
+#define DRAM_TYPE_HIGH_OFFS			20
+#define DRAM_TYPE_HIGH_MASK			0x1
+#define SELF_REFRESH_MODE_OFFS			24
+#define SELF_REFRESH_MODE_MASK			0x1
+#define CPU_RD_PER_PROP_OFFS			25
+#define CPU_RD_PER_PROP_MASK			0x1
+#define DDR4_EMULATION_OFFS			26
+#define DDR4_EMULATION_MASK			0x1
+#define PHY_RF_RST_OFFS				27
+#define PHY_RF_RST_MASK				0x1
+#define PUP_RST_DIVIDER_OFFS			28
+#define PUP_RST_DIVIDER_MASK			0x1
+#define DATA_PUP_WR_RESET_OFFS			29
+#define DATA_PUP_WR_RESET_MASK			0x1
+#define DATA_PUP_RD_RESET_OFFS			30
+#define DATA_PUP_RD_RESET_MASK			0x1
+#define DATA_PUP_RD_RESET_ENA			0x0
+#define DATA_PUP_RD_RESET_DIS			0x1
+#define IO_BIST_OFFS				31
+#define DATA_PUP_RD_RESET_MASK			0x1
+
+#define DUNIT_CTRL_LOW_REG			0x1404
+
+#define SDRAM_TIMING_LOW_REG			0x1408
+#define SDRAM_TIMING_LOW_TRAS_OFFS		0
+#define SDRAM_TIMING_LOW_TRAS_MASK		0xf
+#define SDRAM_TIMING_LOW_TRCD_OFFS		4
+#define SDRAM_TIMING_LOW_TRCD_MASK		0xf
+#define SDRAM_TIMING_HIGH_TRCD_OFFS		22
+#define SDRAM_TIMING_HIGH_TRCD_MASK		0x1
+#define SDRAM_TIMING_LOW_TRP_OFFS		8
+#define SDRAM_TIMING_LOW_TRP_MASK		0xf
+#define SDRAM_TIMING_HIGH_TRP_OFFS		23
+#define SDRAM_TIMING_HIGH_TRP_MASK		0x1
+#define SDRAM_TIMING_LOW_TWR_OFFS		12
+#define SDRAM_TIMING_LOW_TWR_MASK		0xf
+#define SDRAM_TIMING_LOW_TWTR_OFFS		16
+#define SDRAM_TIMING_LOW_TWTR_MASK		0xf
+#define SDRAM_TIMING_LOW_TRAS_HIGH_OFFS		20
+#define SDRAM_TIMING_LOW_TRAS_HIGH_MASK		0x3
+#define SDRAM_TIMING_LOW_TRRD_OFFS		24
+#define SDRAM_TIMING_LOW_TRRD_MASK		0xf
+#define SDRAM_TIMING_LOW_TRTP_OFFS		28
+#define SDRAM_TIMING_LOW_TRTP_MASK		0xf
+
+#define SDRAM_TIMING_HIGH_REG			0x140c
+#define SDRAM_TIMING_HIGH_TRFC_OFFS		0
+#define SDRAM_TIMING_HIGH_TRFC_MASK		0x7f
+#define SDRAM_TIMING_HIGH_TR2R_OFFS		7
+#define SDRAM_TIMING_HIGH_TR2R_MASK		0x3
+#define SDRAM_TIMING_HIGH_TR2W_W2R_OFFS		9
+#define SDRAM_TIMING_HIGH_TR2W_W2R_MASK		0x3
+#define SDRAM_TIMING_HIGH_TW2W_OFFS		11
+#define SDRAM_TIMING_HIGH_TW2W_MASK		0x1f
+#define SDRAM_TIMING_HIGH_TRFC_HIGH_OFFS	16
+#define SDRAM_TIMING_HIGH_TRFC_HIGH_MASK	0x7
+#define SDRAM_TIMING_HIGH_TR2R_HIGH_OFFS	19
+#define SDRAM_TIMING_HIGH_TR2R_HIGH_MASK	0x7
+#define SDRAM_TIMING_HIGH_TR2W_W2R_HIGH_OFFS	22
+#define SDRAM_TIMING_HIGH_TR2W_W2R_HIGH_MASK	0x7
+#define SDRAM_TIMING_HIGH_TMOD_OFFS		25
+#define SDRAM_TIMING_HIGH_TMOD_MASK		0xf
+#define SDRAM_TIMING_HIGH_TMOD_HIGH_OFFS	30
+#define SDRAM_TIMING_HIGH_TMOD_HIGH_MASK	0x3
+
+#define SDRAM_ADDR_CTRL_REG			0x1410
+#define CS_STRUCT_BASE				0
+#define CS_STRUCT_OFFS(cs)			(CS_STRUCT_BASE + (cs) * 4)
+#define CS_STRUCT_MASK				0x3
+#define CS_SIZE_BASE				2
+#define CS_SIZE_OFFS(cs)			(CS_SIZE_BASE + (cs) * 4)
+#define CS_SIZE_MASK				0x3
+#define CS_SIZE_HIGH_BASE			20
+#define CS_SIZE_HIGH_OFFS(cs)			(CS_SIZE_HIGH_BASE + (cs))
+#define CS_SIZE_HIGH_MASK			0x1
+#define T_FAW_OFFS				24
+#define T_FAW_MASK				0x7f
+
+#define SDRAM_OPEN_PAGES_CTRL_REG		0x1414
+
+#define SDRAM_OP_REG				0x1418
+#define SDRAM_OP_CMD_OFFS			0
+#define SDRAM_OP_CMD_MASK			0x1f
+#define SDRAM_OP_CMD_CS_BASE			8
+#define SDRAM_OP_CMD_CS_OFFS(cs)		(SDRAM_OP_CMD_CS_BASE + (cs))
+#define SDRAM_OP_CMD_CS_MASK			0x1
+enum {
+	CMD_NORMAL,
+	CMD_PRECHARGE,
+	CMD_REFRESH,
+	CMD_DDR3_DDR4_MR0,
+	CMD_DDR3_DDR4_MR1,
+	CMD_NOP,
+	CMD_RES_0X6,
+	CMD_SELFREFRESH,
+	CMD_DDR3_DDR4_MR2,
+	CMD_DDR3_DDR4_MR3,
+	CMD_ACT_PDE,
+	CMD_PRE_PDE,
+	CMD_ZQCL,
+	CMD_ZQCS,
+	CMD_CWA,
+	CMD_RES_0XF,
+	CMD_DDR4_MR4,
+	CMD_DDR4_MR5,
+	CMD_DDR4_MR6,
+	DDR4_MPR_WR
+};
+
+#define DUNIT_CTRL_HIGH_REG			0x1424
+#define CPU_INTERJECTION_ENA_OFFS		3
+#define CPU_INTERJECTION_ENA_MASK		0x1
+#define CPU_INTERJECTION_ENA_SPLIT_ENA		0
+#define CPU_INTERJECTION_ENA_SPLIT_DIS		1
+
+#define DDR_ODT_TIMING_LOW_REG			0x1428
+
+#define DDR_TIMING_REG				0x142c
+#define DDR_TIMING_TCCD_OFFS			18
+#define DDR_TIMING_TCCD_MASK			0x7
+#define DDR_TIMING_TPD_OFFS			0
+#define DDR_TIMING_TPD_MASK			0xf
+#define DDR_TIMING_TXPDLL_OFFS			4
+#define DDR_TIMING_TXPDLL_MASK			0x1f
+
+#define DDR_ODT_TIMING_HIGH_REG			0x147c
+
+#define SDRAM_INIT_CTRL_REG			0x1480
+#define DRAM_RESET_MASK_OFFS			1
+#define DRAM_RESET_MASK_MASK			0x1
+#define DRAM_RESET_MASK_NORMAL			0
+#define DRAM_RESET_MASK_MASKED			1
+
+#define SDRAM_ODT_CTRL_HIGH_REG			0x1498
+#define DUNIT_ODT_CTRL_REG			0x149c
+#define RD_BUFFER_SEL_REG			0x14a4
+#define AXI_CTRL_REG				0x14a8
+#define DUNIT_MMASK_REG				0x14b0
+
+#define HORZ_SSTL_CAL_MACH_CTRL_REG		0x14c8
+#define HORZ_POD_CAL_MACH_CTRL_REG		0x17c8
+#define VERT_SSTL_CAL_MACH_CTRL_REG		0x1dc8
+#define VERT_POD_CAL_MACH_CTRL_REG		0x1ec8
+
+#define MAIN_PADS_CAL_MACH_CTRL_REG		0x14cc
+#define DYN_PADS_CAL_ENABLE_OFFS		0
+#define DYN_PADS_CAL_ENABLE_MASK		0x1
+#define DYN_PADS_CAL_ENABLE_DIS			0
+#define DYN_PADS_CAL_ENABLE_ENA			1
+#define PADS_RECAL_OFFS				1
+#define PADS_RECAL_MASK				0x1
+#define DYN_PADS_CAL_BLOCK_OFFS			2
+#define DYN_PADS_CAL_BLOCK_MASK			0x1
+#define CAL_UPDATE_CTRL_OFFS			3
+#define CAL_UPDATE_CTRL_MASK			0x3
+#define CAL_UPDATE_CTRL_INT			1
+#define CAL_UPDATE_CTRL_EXT			2
+#define DYN_PADS_CAL_CNTR_OFFS			13
+#define DYN_PADS_CAL_CNTR_MASK			0x3ffff
+#define CAL_MACH_STATUS_OFFS			31
+#define CAL_MACH_STATUS_MASK			0x1
+#define CAL_MACH_BUSY				0
+#define CAL_MACH_RDY				1
+
+#define DRAM_DLL_TIMING_REG			0x14e0
+#define DRAM_ZQ_INIT_TIMIMG_REG			0x14e4
+#define DRAM_ZQ_TIMING_REG			0x14e8
+
+#define DRAM_LONG_TIMING_REG			0x14ec
+#define DDR4_TRRD_L_OFFS			0
+#define DDR4_TRRD_L_MASK			0xf
+#define DDR4_TWTR_L_OFFS			4
+#define DDR4_TWTR_L_MASK			0xf
+
+#define DDR_IO_REG				0x1524
+#define DFS_REG					0x1528
+
+#define RD_DATA_SMPL_DLYS_REG			0x1538
+#define RD_SMPL_DLY_CS_BASE			0
+#define RD_SMPL_DLY_CS_OFFS(cs)			(RD_SMPL_DLY_CS_BASE + (cs) * 8)
+#define RD_SMPL_DLY_CS_MASK			0x1f
+
+#define RD_DATA_RDY_DLYS_REG			0x153c
+#define RD_RDY_DLY_CS_BASE			0
+#define RD_RDY_DLY_CS_OFFS(cs)			(RD_RDY_DLY_CS_BASE + (cs) * 8)
+#define RD_RDY_DLY_CS_MASK			0x1f
+
+#define TRAINING_REG				0x15b0
+#define TRN_START_OFFS				31
+#define TRN_START_MASK				0x1
+#define TRN_START_ENA				1
+#define TRN_START_DIS				0
+
+#define TRAINING_SW_1_REG			0x15b4
+
+#define TRAINING_SW_2_REG			0x15b8
+#define TRAINING_ECC_MUX_OFFS			1
+#define TRAINING_ECC_MUX_MASK			0x1
+#define TRAINING_ECC_MUX_DIS			0
+#define TRAINING_ECC_MUX_ENA			1
+#define TRAINING_SW_OVRD_OFFS			0
+#define TRAINING_SW_OVRD_MASK			0x1
+#define TRAINING_SW_OVRD_DIS			0
+#define TRAINING_SW_OVRD_ENA			1
+
+#define TRAINING_PATTERN_BASE_ADDR_REG		0x15bc
+#define TRAINING_DBG_1_REG			0x15c0
+#define TRAINING_DBG_2_REG			0x15c4
+
+#define TRAINING_DBG_3_REG			0x15c8
+#define TRN_DBG_RDY_INC_PH_2TO1_BASE		0
+#define TRN_DBG_RDY_INC_PH_2TO1_OFFS(phase)	(TRN_DBG_RDY_INC_PH_2TO1_BASE + (phase) * 3)
+#define TRN_DBG_RDY_INC_PH_2TO1_MASK		0x7
+
+#define DDR3_RANK_CTRL_REG			0x15e0
+#define CS_EXIST_BASE				0
+#define CS_EXIST_OFFS(cs)			(CS_EXIST_BASE + (cs))
+#define CS_EXIST_MASK				0x1
+
+#define ZQC_CFG_REG				0x15e4
+#define DRAM_PHY_CFG_REG			0x15ec
+#define ODPG_CTRL_CTRL_REG			0x1600
+
+#define ODPG_DATA_CTRL_REG			0x1630
+#define ODPG_WRBUF_WR_CTRL_OFFS			0
+#define ODPG_WRBUF_WR_CTRL_MASK			0x1
+#define ODPG_WRBUF_WR_CTRL_DIS			0
+#define ODPG_WRBUF_WR_CTRL_ENA			1
+#define ODPG_WRBUF_RD_CTRL_OFFS			1
+#define ODPG_WRBUF_RD_CTRL_MASK			0x1
+#define ODPG_WRBUF_RD_CTRL_DIS			0
+#define ODPG_WRBUF_RD_CTRL_ENA			1
+#define ODPG_DATA_CBDEL_OFFS			15
+#define ODPG_DATA_CBDEL_MASK			0x3f
+#define ODPG_MODE_OFFS				25
+#define ODPG_MODE_MASK				0x1
+#define ODPG_MODE_RX				0
+#define ODPG_MODE_TX				1
+#define ODPG_DATA_CS_OFFS			26
+#define ODPG_DATA_CS_MASK			0x3
+#define ODPG_DISABLE_OFFS			30
+#define ODPG_DISABLE_MASK			0x1
+#define ODPG_DISABLE_DIS			1
+#define ODPG_ENABLE_OFFS			31
+#define ODPG_ENABLE_MASK			0x1
+#define ODPG_ENABLE_ENA				1
+
+#define ODPG_DATA_BUFFER_OFFS_REG		0x1638
+#define ODPG_DATA_BUFFER_SIZE_REG		0x163c
+#define PHY_LOCK_STATUS_REG			0x1674
+
+#define PHY_REG_FILE_ACCESS_REG			0x16a0
+#define PRFA_DATA_OFFS				0
+#define PRFA_DATA_MASK				0xffff
+#define PRFA_REG_NUM_OFFS			16
+#define PRFA_REG_NUM_MASK			0x3f
+#define PRFA_PUP_NUM_OFFS			22
+#define PRFA_PUP_NUM_MASK			0xf
+#define PRFA_PUP_CTRL_DATA_OFFS			26
+#define PRFA_PUP_CTRL_DATA_MASK			0x1
+#define PRFA_PUP_BCAST_WR_ENA_OFFS		27
+#define PRFA_PUP_BCAST_WR_ENA_MASK		0x1
+#define PRFA_REG_NUM_HI_OFFS			28
+#define PRFA_REG_NUM_HI_MASK			0x3
+#define PRFA_TYPE_OFFS				30
+#define PRFA_TYPE_MASK				0x1
+#define PRFA_REQ_OFFS				31
+#define PRFA_REQ_MASK				0x1
+#define PRFA_REQ_DIS				0x0
+#define PRFA_REQ_ENA				0x1
+
+#define TRAINING_WL_REG				0x16ac
+
+#define ODPG_DATA_WR_ADDR_REG			0x16b0
+#define ODPG_DATA_WR_ACK_OFFS			0
+#define ODPG_DATA_WR_ACK_MASK			0x7f
+#define ODPG_DATA_WR_DATA_OFFS			8
+#define ODPG_DATA_WR_DATA_MASK			0xff
+
+#define ODPG_DATA_WR_DATA_HIGH_REG		0x16b4
+#define ODPG_DATA_WR_DATA_LOW_REG		0x16b8
+#define ODPG_DATA_RX_WORD_ERR_ADDR_REG		0x16bc
+#define ODPG_DATA_RX_WORD_ERR_CNTR_REG		0x16c0
+#define ODPG_DATA_RX_WORD_ERR_DATA_HIGH_REG	0x16c4
+#define ODPG_DATA_RX_WORD_ERR_DATA_LOW_REG	0x16c8
+#define ODPG_DATA_WR_DATA_ERR_REG		0x16cc
+
+#define DUAL_DUNIT_CFG_REG			0x16d8
+#define FC_SAMPLE_STAGES_OFFS			0
+#define FC_SAMPLE_STAGES_MASK			0x7
+#define SINGLE_CS_PIN_OFFS			3
+#define SINGLE_CS_PIN_MASK			0x1
+#define SINGLE_CS_ENA				1
+#define TUNING_ACTIVE_SEL_OFFS			6
+#define TUNING_ACTIVE_SEL_MASK			0x1
+#define TUNING_ACTIVE_SEL_MC			0
+#define TUNING_ACTIVE_SEL_TIP			1
+
+#define WL_DQS_PATTERN_REG			0x16dc
+#define ODPG_DONE_STATUS_REG			0x16fc
+#define ODPG_DONE_STATUS_BIT_OFFS		0
+#define ODPG_DONE_STATUS_BIT_MASK		0x1
+#define ODPG_DONE_STATUS_BIT_CLR		0
+#define ODPG_DONE_STATUS_BIT_SET		1
+
+#define RESULT_CTRL_BASE			0x1830
+#define BLOCK_STATUS_OFFS			25
+#define BLOCK_STATUS_MASK			0x1
+#define BLOCK_STATUS_LOCK			1
+#define BLOCK_STATUS_NOT_LOCKED			0
+
+#define MR0_REG					0x15d0
+#define MR1_REG					0x15d4
+#define MR2_REG					0x15d8
+#define MR3_REG					0x15dc
+#define MRS0_CMD				0x3
+#define MRS1_CMD				0x4
+#define MRS2_CMD				0x8
+#define MRS3_CMD				0x9
+
+
+#define DRAM_PINS_MUX_REG			0x19d4
+#define CTRL_PINS_MUX_OFFS			0
+#define CTRL_PINS_MUX_MASK			0x3
+enum {
+	DUNIT_DDR3_ON_BOARD,
+	DUNIT_DDR3_DIMM,
+	DUNIT_DDR4_ON_BOARD,
+	DUNIT_DDR4_DIMM
+};
+
+/* ddr phy registers */
+#define WL_PHY_BASE				0x0
+#define WL_PHY_REG(cs)				(WL_PHY_BASE + (cs) * 0x4)
+#define WR_LVL_PH_SEL_OFFS			6
+#define WR_LVL_PH_SEL_MASK			0x7
+#define WR_LVL_PH_SEL_PHASE1			1
+#define WR_LVL_REF_DLY_OFFS			0
+#define WR_LVL_REF_DLY_MASK			0x1f
+#define CTRL_CENTER_DLY_OFFS			10
+#define CTRL_CENTER_DLY_MASK			0x1f
+#define CTRL_CENTER_DLY_INV_OFFS		15
+#define CTRL_CENTER_DLY_INV_MASK		0x1
+
+#define CTX_PHY_BASE				0x1
+#define CTX_PHY_REG(cs)				(CTX_PHY_BASE + (cs) * 0x4)
+
+#define RL_PHY_BASE				0x2
+#define RL_PHY_REG(cs)				(RL_PHY_BASE + (cs) * 0x4)
+#define RL_REF_DLY_OFFS				0
+#define RL_REF_DLY_MASK				0x1f
+#define RL_PH_SEL_OFFS				6
+#define RL_PH_SEL_MASK				0x7
+
+#define CRX_PHY_BASE				0x3
+#define CRX_PHY_REG(cs)				(CRX_PHY_BASE + (cs) * 0x4)
+
+#define PHY_CTRL_PHY_REG			0x90
+#define ADLL_CFG0_PHY_REG			0x92
+#define ADLL_CFG1_PHY_REG			0x93
+#define ADLL_CFG2_PHY_REG			0x94
+#define CMOS_CONFIG_PHY_REG			0xa2
+#define PAD_ZRI_CAL_PHY_REG			0xa4
+#define PAD_ODT_CAL_PHY_REG			0xa6
+#define PAD_CFG_PHY_REG				0xa8
+#define PAD_PRE_DISABLE_PHY_REG			0xa9
+#define TEST_ADLL_PHY_REG			0xbf
+
+#define VREF_PHY_BASE				0xd0
+#define VREF_PHY_REG(cs, bit)			(VREF_PHY_BASE + (cs) * 12 + bit)
+enum {
+	DQSP_PAD = 4,
+	DQSN_PAD
+};
+
+#define VREF_BCAST_PHY_BASE			0xdb
+#define VREF_BCAST_PHY_REG(cs)			(VREF_BCAST_PHY_BASE + (cs) * 12)
+
+#define PBS_TX_PHY_BASE				0x10
+#define PBS_TX_PHY_REG(cs, bit)			(PBS_TX_PHY_BASE + (cs) * 0x10 + (bit))
+
+#define PBS_TX_BCAST_PHY_BASE			0x1f
+#define PBS_TX_BCAST_PHY_REG(cs)		(PBS_TX_BCAST_PHY_BASE + (cs) * 0x10)
+
+#define PBS_RX_PHY_BASE				0x50
+#define PBS_RX_PHY_REG(cs, bit)			(PBS_RX_PHY_BASE + (cs) * 0x10 + (bit))
+
+#define PBS_RX_BCAST_PHY_BASE			0x5f
+#define PBS_RX_BCAST_PHY_REG(cs)		(PBS_RX_BCAST_PHY_BASE + (cs) * 0x10)
+
+#define RESULT_PHY_REG				0xc0
+#define RESULT_PHY_RX_OFFS			5
+#define RESULT_PHY_TX_OFFS			0
+
+
+#endif /* _MV_DDR_REGS_H */
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_spd.c b/drivers/ddr/marvell/a38x/mv_ddr_spd.c
new file mode 100644
index 000000000000..eaf6597e43ce
--- /dev/null
+++ b/drivers/ddr/marvell/a38x/mv_ddr_spd.c
@@ -0,0 +1,378 @@
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include "mv_ddr_spd.h"
+
+#define MV_DDR_SPD_DATA_MTB		125	/* medium timebase, ps */
+#define MV_DDR_SPD_DATA_FTB		1	/* fine timebase, ps */
+#define MV_DDR_SPD_MSB_OFFS		8	/* most significant byte offset, bits */
+
+#define MV_DDR_SPD_SUPPORTED_CLS_NUM	30
+
+static unsigned int mv_ddr_spd_supported_cls[MV_DDR_SPD_SUPPORTED_CLS_NUM];
+
+int mv_ddr_spd_supported_cls_calc(union mv_ddr_spd_data *spd_data)
+{
+	unsigned int byte, bit, start_cl;
+
+	start_cl = (spd_data->all_bytes[23] & 0x8) ? 23 : 7;
+
+	for (byte = 20; byte < 23; byte++) {
+		for (bit = 0; bit < 8; bit++) {
+			if (spd_data->all_bytes[byte] & (1 << bit))
+				mv_ddr_spd_supported_cls[(byte - 20) * 8 + bit] = start_cl + (byte - 20) * 8 + bit;
+			else
+				mv_ddr_spd_supported_cls[(byte - 20) * 8 + bit] = 0;
+		}
+	}
+
+	for (byte = 23, bit = 0; bit < 6; bit++) {
+		if (spd_data->all_bytes[byte] & (1 << bit))
+			mv_ddr_spd_supported_cls[(byte - 20) * 8 + bit] = start_cl + (byte - 20) * 8 + bit;
+		else
+			mv_ddr_spd_supported_cls[(byte - 20) * 8 + bit] = 0;
+	}
+
+	return 0;
+}
+
+unsigned int mv_ddr_spd_supported_cl_get(unsigned int cl)
+{
+	unsigned int supported_cl;
+	int i = 0;
+
+	while (i < MV_DDR_SPD_SUPPORTED_CLS_NUM &&
+		mv_ddr_spd_supported_cls[i] < cl)
+		i++;
+
+	if (i < MV_DDR_SPD_SUPPORTED_CLS_NUM)
+		supported_cl = mv_ddr_spd_supported_cls[i];
+	else
+		supported_cl = 0;
+
+	return supported_cl;
+}
+
+int mv_ddr_spd_timing_calc(union mv_ddr_spd_data *spd_data, unsigned int timing_data[])
+{
+	int calc_val;
+
+	/* t ck avg min, ps */
+	calc_val = spd_data->byte_fields.byte_18 * MV_DDR_SPD_DATA_MTB +
+		(signed char)spd_data->byte_fields.byte_125 * MV_DDR_SPD_DATA_FTB;
+	if (calc_val < 0)
+		return 1;
+	timing_data[MV_DDR_TCK_AVG_MIN] = calc_val;
+
+	/* t aa min, ps */
+	calc_val = spd_data->byte_fields.byte_24 * MV_DDR_SPD_DATA_MTB +
+		(signed char)spd_data->byte_fields.byte_123 * MV_DDR_SPD_DATA_FTB;
+	if (calc_val < 0)
+		return 1;
+	timing_data[MV_DDR_TAA_MIN] = calc_val;
+
+	/* t rfc1 min, ps */
+	timing_data[MV_DDR_TRFC1_MIN] = (spd_data->byte_fields.byte_30 +
+		(spd_data->byte_fields.byte_31 << MV_DDR_SPD_MSB_OFFS)) * MV_DDR_SPD_DATA_MTB;
+
+	/* t wr min, ps */
+	timing_data[MV_DDR_TWR_MIN] = (spd_data->byte_fields.byte_42 +
+		(spd_data->byte_fields.byte_41.bit_fields.t_wr_min_msn << MV_DDR_SPD_MSB_OFFS)) *
+		MV_DDR_SPD_DATA_MTB;
+	/* FIXME: wa: set twr to a default value, if it's unset on spd */
+	if (timing_data[MV_DDR_TWR_MIN] == 0)
+		timing_data[MV_DDR_TWR_MIN] = 15000;
+
+	/* t rcd min, ps */
+	calc_val = spd_data->byte_fields.byte_25 * MV_DDR_SPD_DATA_MTB +
+		(signed char)spd_data->byte_fields.byte_122 * MV_DDR_SPD_DATA_FTB;
+	if (calc_val < 0)
+		return 1;
+	timing_data[MV_DDR_TRCD_MIN] = calc_val;
+
+	/* t rp min, ps */
+	calc_val = spd_data->byte_fields.byte_26 * MV_DDR_SPD_DATA_MTB +
+		(signed char)spd_data->byte_fields.byte_121 * MV_DDR_SPD_DATA_FTB;
+	if (calc_val < 0)
+		return 1;
+	timing_data[MV_DDR_TRP_MIN] = calc_val;
+
+	/* t rc min, ps */
+	calc_val = (spd_data->byte_fields.byte_29 +
+		(spd_data->byte_fields.byte_27.bit_fields.t_rc_min_msn << MV_DDR_SPD_MSB_OFFS)) *
+		MV_DDR_SPD_DATA_MTB +
+		(signed char)spd_data->byte_fields.byte_120 * MV_DDR_SPD_DATA_FTB;
+	if (calc_val < 0)
+		return 1;
+	timing_data[MV_DDR_TRC_MIN] = calc_val;
+
+	/* t ras min, ps */
+	timing_data[MV_DDR_TRAS_MIN] = (spd_data->byte_fields.byte_28 +
+		(spd_data->byte_fields.byte_27.bit_fields.t_ras_min_msn << MV_DDR_SPD_MSB_OFFS)) *
+		MV_DDR_SPD_DATA_MTB;
+
+	/* t rrd s min, ps */
+	calc_val = spd_data->byte_fields.byte_38 * MV_DDR_SPD_DATA_MTB +
+		(signed char)spd_data->byte_fields.byte_119 * MV_DDR_SPD_DATA_FTB;
+	if (calc_val < 0)
+		return 1;
+	timing_data[MV_DDR_TRRD_S_MIN] = calc_val;
+
+	/* t rrd l min, ps */
+	calc_val = spd_data->byte_fields.byte_39 * MV_DDR_SPD_DATA_MTB +
+		(signed char)spd_data->byte_fields.byte_118 * MV_DDR_SPD_DATA_FTB;
+	if (calc_val < 0)
+		return 1;
+	timing_data[MV_DDR_TRRD_L_MIN] = calc_val;
+
+	/* t faw min, ps */
+	timing_data[MV_DDR_TFAW_MIN] = (spd_data->byte_fields.byte_37 +
+		(spd_data->byte_fields.byte_36.bit_fields.t_faw_min_msn << MV_DDR_SPD_MSB_OFFS)) *
+		MV_DDR_SPD_DATA_MTB;
+
+	/* t wtr s min, ps */
+	timing_data[MV_DDR_TWTR_S_MIN] = (spd_data->byte_fields.byte_44 +
+		(spd_data->byte_fields.byte_43.bit_fields.t_wtr_s_min_msn << MV_DDR_SPD_MSB_OFFS)) *
+		MV_DDR_SPD_DATA_MTB;
+	/* FIXME: wa: set twtr_s to a default value, if it's unset on spd */
+	if (timing_data[MV_DDR_TWTR_S_MIN] == 0)
+		timing_data[MV_DDR_TWTR_S_MIN] = 2500;
+
+	/* t wtr l min, ps */
+	timing_data[MV_DDR_TWTR_L_MIN] = (spd_data->byte_fields.byte_45 +
+		(spd_data->byte_fields.byte_43.bit_fields.t_wtr_l_min_msn << MV_DDR_SPD_MSB_OFFS)) *
+		MV_DDR_SPD_DATA_MTB;
+	/* FIXME: wa: set twtr_l to a default value, if it's unset on spd */
+	if (timing_data[MV_DDR_TWTR_L_MIN] == 0)
+		timing_data[MV_DDR_TWTR_L_MIN] = 7500;
+
+	return 0;
+}
+
+enum mv_ddr_dev_width mv_ddr_spd_dev_width_get(union mv_ddr_spd_data *spd_data)
+{
+	unsigned char dev_width = spd_data->byte_fields.byte_12.bit_fields.device_width;
+	enum mv_ddr_dev_width ret_val;
+
+	switch (dev_width) {
+	case 0x00:
+		ret_val = MV_DDR_DEV_WIDTH_4BIT;
+		break;
+	case 0x01:
+		ret_val = MV_DDR_DEV_WIDTH_8BIT;
+		break;
+	case 0x02:
+		ret_val = MV_DDR_DEV_WIDTH_16BIT;
+		break;
+	case 0x03:
+		ret_val = MV_DDR_DEV_WIDTH_32BIT;
+		break;
+	default:
+		ret_val = MV_DDR_DEV_WIDTH_LAST;
+	}
+
+	return ret_val;
+}
+
+enum mv_ddr_die_capacity mv_ddr_spd_die_capacity_get(union mv_ddr_spd_data *spd_data)
+{
+	unsigned char die_cap = spd_data->byte_fields.byte_4.bit_fields.die_capacity;
+	enum mv_ddr_die_capacity ret_val;
+
+	switch (die_cap) {
+	case 0x00:
+		ret_val = MV_DDR_DIE_CAP_256MBIT;
+		break;
+	case 0x01:
+		ret_val = MV_DDR_DIE_CAP_512MBIT;
+		break;
+	case 0x02:
+		ret_val = MV_DDR_DIE_CAP_1GBIT;
+		break;
+	case 0x03:
+		ret_val = MV_DDR_DIE_CAP_2GBIT;
+		break;
+	case 0x04:
+		ret_val = MV_DDR_DIE_CAP_4GBIT;
+		break;
+	case 0x05:
+		ret_val = MV_DDR_DIE_CAP_8GBIT;
+		break;
+	case 0x06:
+		ret_val = MV_DDR_DIE_CAP_16GBIT;
+		break;
+	case 0x07:
+		ret_val = MV_DDR_DIE_CAP_32GBIT;
+		break;
+	case 0x08:
+		ret_val = MV_DDR_DIE_CAP_12GBIT;
+		break;
+	case 0x09:
+		ret_val = MV_DDR_DIE_CAP_24GBIT;
+		break;
+	default:
+		ret_val = MV_DDR_DIE_CAP_LAST;
+	}
+
+	return ret_val;
+}
+
+unsigned char mv_ddr_spd_mem_mirror_get(union mv_ddr_spd_data *spd_data)
+{
+	unsigned char mem_mirror = spd_data->byte_fields.byte_131.bit_fields.rank_1_mapping;
+
+	return mem_mirror;
+}
+
+enum mv_ddr_pkg_rank mv_ddr_spd_pri_bus_width_get(union mv_ddr_spd_data *spd_data)
+{
+	unsigned char pri_bus_width = spd_data->byte_fields.byte_13.bit_fields.primary_bus_width;
+	enum mv_ddr_pri_bus_width ret_val;
+
+	switch (pri_bus_width) {
+	case 0x00:
+		ret_val = MV_DDR_PRI_BUS_WIDTH_8;
+		break;
+	case 0x01:
+		ret_val = MV_DDR_PRI_BUS_WIDTH_16;
+		break;
+	case 0x02:
+		ret_val = MV_DDR_PRI_BUS_WIDTH_32;
+		break;
+	case 0x03:
+		ret_val = MV_DDR_PRI_BUS_WIDTH_64;
+		break;
+	default:
+		ret_val = MV_DDR_PRI_BUS_WIDTH_LAST;
+	}
+
+	return ret_val;
+}
+
+enum mv_ddr_pkg_rank mv_ddr_spd_bus_width_ext_get(union mv_ddr_spd_data *spd_data)
+{
+	unsigned char bus_width_ext = spd_data->byte_fields.byte_13.bit_fields.bus_width_ext;
+	enum mv_ddr_bus_width_ext ret_val;
+
+	switch (bus_width_ext) {
+	case 0x00:
+		ret_val = MV_DDR_BUS_WIDTH_EXT_0;
+		break;
+	case 0x01:
+		ret_val = MV_DDR_BUS_WIDTH_EXT_8;
+		break;
+	default:
+		ret_val = MV_DDR_BUS_WIDTH_EXT_LAST;
+	}
+
+	return ret_val;
+}
+
+static enum mv_ddr_pkg_rank mv_ddr_spd_pkg_rank_get(union mv_ddr_spd_data *spd_data)
+{
+	unsigned char pkg_rank = spd_data->byte_fields.byte_12.bit_fields.dimm_pkg_ranks_num;
+	enum mv_ddr_pkg_rank ret_val;
+
+	switch (pkg_rank) {
+	case 0x00:
+		ret_val = MV_DDR_PKG_RANK_1;
+		break;
+	case 0x01:
+		ret_val = MV_DDR_PKG_RANK_2;
+		break;
+	case 0x02:
+		ret_val = MV_DDR_PKG_RANK_3;
+		break;
+	case 0x03:
+		ret_val = MV_DDR_PKG_RANK_4;
+		break;
+	case 0x04:
+		ret_val = MV_DDR_PKG_RANK_5;
+		break;
+	case 0x05:
+		ret_val = MV_DDR_PKG_RANK_6;
+		break;
+	case 0x06:
+		ret_val = MV_DDR_PKG_RANK_7;
+		break;
+	case 0x07:
+		ret_val = MV_DDR_PKG_RANK_8;
+		break;
+	default:
+		ret_val = MV_DDR_PKG_RANK_LAST;
+	}
+
+	return ret_val;
+}
+
+static enum mv_ddr_die_count mv_ddr_spd_die_count_get(union mv_ddr_spd_data *spd_data)
+{
+	unsigned char die_count = spd_data->byte_fields.byte_6.bit_fields.die_count;
+	enum mv_ddr_die_count ret_val;
+
+	switch (die_count) {
+	case 0x00:
+		ret_val = MV_DDR_DIE_CNT_1;
+		break;
+	case 0x01:
+		ret_val = MV_DDR_DIE_CNT_2;
+		break;
+	case 0x02:
+		ret_val = MV_DDR_DIE_CNT_3;
+		break;
+	case 0x03:
+		ret_val = MV_DDR_DIE_CNT_4;
+		break;
+	case 0x04:
+		ret_val = MV_DDR_DIE_CNT_5;
+		break;
+	case 0x05:
+		ret_val = MV_DDR_DIE_CNT_6;
+		break;
+	case 0x06:
+		ret_val = MV_DDR_DIE_CNT_7;
+		break;
+	case 0x07:
+		ret_val = MV_DDR_DIE_CNT_8;
+		break;
+	default:
+		ret_val = MV_DDR_DIE_CNT_LAST;
+	}
+
+	return ret_val;
+}
+
+unsigned char mv_ddr_spd_cs_bit_mask_get(union mv_ddr_spd_data *spd_data)
+{
+	unsigned char cs_bit_mask = 0x0;
+	enum mv_ddr_pkg_rank pkg_rank = mv_ddr_spd_pkg_rank_get(spd_data);
+	enum mv_ddr_die_count die_cnt = mv_ddr_spd_die_count_get(spd_data);
+
+	if (pkg_rank == MV_DDR_PKG_RANK_1 && die_cnt == MV_DDR_DIE_CNT_1)
+		cs_bit_mask = 0x1;
+	else if (pkg_rank == MV_DDR_PKG_RANK_1 && die_cnt == MV_DDR_DIE_CNT_2)
+		cs_bit_mask = 0x3;
+	else if (pkg_rank == MV_DDR_PKG_RANK_2 && die_cnt == MV_DDR_DIE_CNT_1)
+		cs_bit_mask = 0x3;
+	else if (pkg_rank == MV_DDR_PKG_RANK_2 && die_cnt == MV_DDR_DIE_CNT_2)
+		cs_bit_mask = 0xf;
+
+	return cs_bit_mask;
+}
+
+unsigned char mv_ddr_spd_dev_type_get(union mv_ddr_spd_data *spd_data)
+{
+	unsigned char dev_type = spd_data->byte_fields.byte_2;
+
+	return dev_type;
+}
+
+unsigned char mv_ddr_spd_module_type_get(union mv_ddr_spd_data *spd_data)
+{
+	unsigned char module_type = spd_data->byte_fields.byte_3.bit_fields.module_type;
+
+	return module_type;
+}
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_spd.h b/drivers/ddr/marvell/a38x/mv_ddr_spd.h
new file mode 100644
index 000000000000..b14293f8f0e2
--- /dev/null
+++ b/drivers/ddr/marvell/a38x/mv_ddr_spd.h
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#ifndef _MV_DDR_SPD_H
+#define _MV_DDR_SPD_H
+
+#include "mv_ddr_topology.h"
+
+/*
+ * Based on JEDEC Standard No. 21-C, 4.1.2.L-4:
+ * Serial Presence Detect (SPD) for DDR4 SDRAM Modules
+ */
+
+/* block 0: base configuration and dram parameters */
+#define MV_DDR_SPD_DATA_BLOCK0_SIZE		128
+/* block 1: module specific parameters sub-block */
+#define MV_DDR_SPD_DATA_BLOCK1M_SIZE		64
+/* block 1: hybrid memory parameters sub-block */
+#define MV_DDR_SPD_DATA_BLOCK1H_SIZE		64
+/* block 2: extended function parameter block */
+#define MV_DDR_SPD_DATA_BLOCK2E_SIZE		64
+/* block 2: manufacturing information */
+#define MV_DDR_SPD_DATA_BLOCK2M_SIZE		64
+/* block 3: end user programmable */
+#define MV_DDR_SPD_DATA_BLOCK3_SIZE		128
+
+#define MV_DDR_SPD_DEV_TYPE_DDR4		0xc
+#define MV_DDR_SPD_MODULE_TYPE_UDIMM		0x2
+#define MV_DDR_SPD_MODULE_TYPE_SO_DIMM		0x3
+#define MV_DDR_SPD_MODULE_TYPE_MINI_UDIMM	0x6
+#define MV_DDR_SPD_MODULE_TYPE_72BIT_SO_UDIMM	0x9
+#define MV_DDR_SPD_MODULE_TYPE_16BIT_SO_DIMM	0xc
+#define MV_DDR_SPD_MODULE_TYPE_32BIT_SO_DIMM	0xd
+
+/*
+ * TODO: For now, the struct contains block 0 & block 1 with module specific
+ * parameters for unbuffered memory module types only.
+ */
+union mv_ddr_spd_data {
+	unsigned char all_bytes[MV_DDR_SPD_DATA_BLOCK0_SIZE +
+				MV_DDR_SPD_DATA_BLOCK1M_SIZE];
+	struct {
+		/* block 0 */
+		union { /* num of bytes used/num of bytes in spd device/crc coverage */
+			unsigned char all_bits;
+			struct {
+				unsigned char spd_bytes_used:4,
+					spd_bytes_total:3,
+					reserved:1;
+			} bit_fields;
+		} byte_0;
+		union { /* spd revision */
+			unsigned char all_bits;
+			struct {
+				unsigned char addtions_level:4,
+					encoding_level:4;
+			} bit_fields;
+		} byte_1;
+		unsigned char  byte_2; /* key_byte/dram device type */
+		union { /* key byte/module type */
+			unsigned char all_bits;
+			struct {
+				unsigned char module_type:4,
+					hybrid_media:3,
+					hybrid:1;
+			} bit_fields;
+		} byte_3;
+		union { /* sdram density & banks */
+			unsigned char all_bits;
+			struct {
+				unsigned char die_capacity:4,
+					bank_address:2,
+					bank_group:2;
+			} bit_fields;
+		} byte_4;
+		union { /* sdram addressing */
+			unsigned char all_bits;
+			struct {
+				unsigned char col_address:3,
+					row_address:3,
+					reserved:2;
+			} bit_fields;
+		} byte_5;
+		union { /* sdram package type */
+			unsigned char all_bits;
+			struct {
+				unsigned char signal_loading:2,
+					reserved:2,
+					die_count:3,
+					sdram_package_type:1;
+			} bit_fields;
+		} byte_6;
+		union { /* sdram optional features */
+			unsigned char all_bits;
+			struct {
+				unsigned char mac:4, /* max activate count */
+					t_maw:2, /* max activate window */
+					reserved:2; /* all 0s */
+			} bit_fields;
+		} byte_7;
+		unsigned char byte_8; /* sdram thermal & refresh options; reserved; 0x00 */
+		union { /* other sdram optional features */
+			unsigned char all_bits;
+			struct {
+				unsigned char reserved:5, /* all 0s */
+					soft_ppr:1,
+					ppr:2; /* post package repair */
+			} bit_fields;
+		} byte_9;
+		union { /* secondary sdram package type */
+			unsigned char all_bits;
+			struct {
+				unsigned char signal_loading:2,
+					density_ratio:2, /* dram density ratio */
+					die_count:3,
+					sdram_package_type:1;
+			} bit_fields;
+		} byte_10;
+		union { /* module nominal voltage, vdd */
+			unsigned char all_bits;
+			struct {
+				unsigned char operable:1,
+					endurant:1,
+					reserved:5; /* all 0s */
+			} bit_fields;
+		} byte_11;
+		union { /* module organization*/
+			unsigned char all_bits;
+			struct {
+				unsigned char device_width:3,
+					dimm_pkg_ranks_num:3, /* package ranks per dimm number */
+					rank_mix:1,
+					reserved:1; /* 0 */
+			} bit_fields;
+		} byte_12;
+		union { /* module memory bus width */
+			unsigned char all_bits;
+			struct {
+				unsigned char primary_bus_width:3, /* in bits */
+					bus_width_ext:2, /* in bits */
+					reserved:3; /* all 0s */
+			} bit_fields;
+		} byte_13;
+		union { /* module thernal sensor */
+			unsigned char all_bits;
+			struct {
+				unsigned char reserved:7,
+					thermal_sensor:1;
+			} bit_fields;
+		} byte_14;
+		union { /* extended module type */
+			unsigned char all_bits;
+			struct {
+				unsigned char ext_base_module_type:4,
+					reserved:4; /* all 0s */
+			} bit_fields;
+		} byte_15;
+		unsigned char byte_16; /* reserved; 0x00 */
+		union { /* timebases */
+			unsigned char all_bits;
+			struct {
+				unsigned char ftb:2, /* fine timebase */
+					mtb:2, /* medium timebase */
+					reserved:4; /* all 0s */
+			} bit_fields;
+		} byte_17;
+		unsigned char byte_18; /* sdram min cycle time (t ck avg min), mtb */
+		unsigned char byte_19; /* sdram max cycle time (t ck avg max), mtb */
+		unsigned char byte_20; /* cas latencies supported, first byte */
+		unsigned char byte_21; /* cas latencies supported, second byte */
+		unsigned char byte_22; /* cas latencies supported, third byte */
+		unsigned char byte_23; /* cas latencies supported, fourth byte */
+		unsigned char byte_24; /* min cas latency time (t aa min), mtb */
+		unsigned char byte_25; /* min ras to cas delay time (t rcd min), mtb */
+		unsigned char byte_26; /* min row precharge delay time (t rp min), mtb */
+		union { /* upper nibbles for t ras min & t rc min */
+			unsigned char all_bits;
+			struct {
+				unsigned char t_ras_min_msn:4, /* t ras min most significant nibble */
+					t_rc_min_msn:4; /* t rc min most significant nibble */
+			} bit_fields;
+		} byte_27;
+		unsigned char byte_28; /* min active to precharge delay time (t ras min), l-s-byte, mtb */
+		unsigned char byte_29; /* min active to active/refresh delay time (t rc min), l-s-byte, mtb */
+		unsigned char byte_30; /* min refresh recovery delay time (t rfc1 min), l-s-byte, mtb */
+		unsigned char byte_31; /* min refresh recovery delay time (t rfc1 min), m-s-byte, mtb */
+		unsigned char byte_32; /* min refresh recovery delay time (t rfc2 min), l-s-byte, mtb */
+		unsigned char byte_33; /* min refresh recovery delay time (t rfc2 min), m-s-byte, mtb */
+		unsigned char byte_34; /* min refresh recovery delay time (t rfc4 min), l-s-byte, mtb */
+		unsigned char byte_35; /* min refresh recovery delay time (t rfc4 min), m-s-byte, mtb */
+		union { /* upper nibble for t faw */
+			unsigned char all_bits;
+			struct {
+				unsigned char t_faw_min_msn:4, /* t faw min most significant nibble */
+					reserved:4;
+			} bit_fields;
+		} byte_36;
+		unsigned char byte_37; /* min four activate window delay time (t faw min), l-s-byte, mtb */
+		/* byte 38: min activate to activate delay time (t rrd_s min), diff bank group, mtb */
+		unsigned char byte_38;
+		/* byte 39: min activate to activate delay time (t rrd_l min), same bank group, mtb */
+		unsigned char byte_39;
+		unsigned char byte_40; /* min cas to cas delay time (t ccd_l min), same bank group, mtb */
+		union { /* upper nibble for t wr min */
+			unsigned char all_bits;
+			struct {
+				unsigned char t_wr_min_msn:4, /* t wr min most significant nibble */
+					reserved:4;
+			} bit_fields;
+		} byte_41;
+		unsigned char byte_42; /* min write recovery time (t wr min) */
+		union { /* upper nibbles for t wtr min */
+			unsigned char all_bits;
+			struct {
+				unsigned char t_wtr_s_min_msn:4, /* t wtr s min most significant nibble */
+					t_wtr_l_min_msn:4; /* t wtr l min most significant nibble */
+			} bit_fields;
+		} byte_43;
+		unsigned char byte_44; /* min write to read time (t wtr s min), diff bank group, mtb */
+		unsigned char byte_45; /* min write to read time (t wtr l min), same bank group, mtb */
+		unsigned char bytes_46_59[14]; /* reserved; all 0s */
+		unsigned char bytes_60_77[18]; /* TODO: connector to sdram bit mapping */
+		unsigned char bytes_78_116[39]; /* reserved; all 0s */
+		/* fine offset for min cas to cas delay time (t ccd_l min), same bank group, ftb */
+		unsigned char byte_117;
+		/* fine offset for min activate to activate delay time (t rrd_l min), same bank group, ftb */
+		unsigned char byte_118;
+		/* fine offset for min activate to activate delay time (t rrd_s min), diff bank group, ftb */
+		unsigned char byte_119;
+		/* fine offset for min active to active/refresh delay time (t rc min), ftb */
+		unsigned char byte_120;
+		unsigned char byte_121; /* fine offset for min row precharge delay time (t rp min), ftb */
+		unsigned char byte_122; /* fine offset for min ras to cas delay time (t rcd min), ftb */
+		unsigned char byte_123; /* fine offset for min cas latency time (t aa min), ftb */
+		unsigned char byte_124; /* fine offset for sdram max cycle time (t ck avg max), ftb */
+		unsigned char byte_125; /* fine offset for sdram min cycle time (t ck avg min), ftb */
+		unsigned char byte_126; /* crc for base configuration section, l-s-byte */
+		unsigned char byte_127; /* crc for base configuration section, m-s-byte */
+		/*
+		 * block 1: module specific parameters for unbuffered memory module types only
+		 */
+		union { /* (unbuffered) raw card extension, module nominal height */
+			unsigned char all_bits;
+			struct {
+				unsigned char nom_height_max:5, /* in mm */
+					raw_cad_ext:3;
+			} bit_fields;
+		} byte_128;
+		union { /* (unbuffered) module maximum thickness */
+			unsigned char all_bits;
+			struct {
+				unsigned char front_thickness_max:4, /* in mm */
+					back_thickness_max:4; /* in mm */
+			} bit_fields;
+		} byte_129;
+		union { /* (unbuffered) reference raw card used */
+			unsigned char all_bits;
+			struct {
+				unsigned char ref_raw_card:5,
+					ref_raw_card_rev:2,
+					ref_raw_card_ext:1;
+			} bit_fields;
+		} byte_130;
+		union { /* (unbuffered) address mapping from edge connector to dram */
+			unsigned char all_bits;
+			struct {
+				unsigned char rank_1_mapping:1,
+					reserved:7;
+			} bit_fields;
+		} byte_131;
+		unsigned char bytes_132_191[60]; /* reserved; all 0s */
+	} byte_fields;
+};
+
+int mv_ddr_spd_timing_calc(union mv_ddr_spd_data *spd_data, unsigned int timing_data[]);
+enum mv_ddr_dev_width mv_ddr_spd_dev_width_get(union mv_ddr_spd_data *spd_data);
+enum mv_ddr_die_capacity mv_ddr_spd_die_capacity_get(union mv_ddr_spd_data *spd_data);
+unsigned char mv_ddr_spd_mem_mirror_get(union mv_ddr_spd_data *spd_data);
+unsigned char mv_ddr_spd_cs_bit_mask_get(union mv_ddr_spd_data *spd_data);
+unsigned char mv_ddr_spd_dev_type_get(union mv_ddr_spd_data *spd_data);
+unsigned char mv_ddr_spd_module_type_get(union mv_ddr_spd_data *spd_data);
+int mv_ddr_spd_supported_cls_calc(union mv_ddr_spd_data *spd_data);
+unsigned int mv_ddr_spd_supported_cl_get(unsigned int cl);
+enum mv_ddr_pkg_rank mv_ddr_spd_pri_bus_width_get(union mv_ddr_spd_data *spd_data);
+enum mv_ddr_pkg_rank mv_ddr_spd_bus_width_ext_get(union mv_ddr_spd_data *spd_data);
+
+#endif /* _MV_DDR_SPD_H */
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.c b/drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.c
new file mode 100644
index 000000000000..505ba28fe28f
--- /dev/null
+++ b/drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include "mv_ddr_regs.h"
+#include "mv_ddr_sys_env_lib.h"
+
+static u32 mv_ddr_board_id_get(void)
+{
+#if defined(CONFIG_TARGET_DB_88F6820_GP)
+	return DB_GP_68XX_ID;
+#else
+	/*
+	 * Return 0 here for custom board as this should not be used
+	 * for custom boards.
+	 */
+	return 0;
+#endif
+}
+
+static u32 mv_ddr_board_id_index_get(u32 board_id)
+{
+	/*
+	 * Marvell Boards use 0x10 as base for Board ID:
+	 * mask MSB to receive index for board ID
+	 */
+	return board_id & (MARVELL_BOARD_ID_MASK - 1);
+}
+
+/*
+ * read gpio input for suspend-wakeup indication
+ * return indicating suspend wakeup status:
+ * 0 - not supported,
+ * 1 - supported: read magic word detect wakeup,
+ * 2 - detected wakeup from gpio
+ */
+enum suspend_wakeup_status mv_ddr_sys_env_suspend_wakeup_check(void)
+{
+	u32 reg, board_id_index, gpio;
+	struct board_wakeup_gpio board_gpio[] = MV_BOARD_WAKEUP_GPIO_INFO;
+
+	board_id_index = mv_ddr_board_id_index_get(mv_ddr_board_id_get());
+	if (!(sizeof(board_gpio) / sizeof(struct board_wakeup_gpio) >
+	      board_id_index)) {
+		printf("\n_failed loading Suspend-Wakeup information (invalid board ID)\n");
+		return SUSPEND_WAKEUP_DISABLED;
+	}
+
+	/*
+	 * - Detect if Suspend-Wakeup is supported on current board
+	 * - Fetch the GPIO number for wakeup status input indication
+	 */
+	if (board_gpio[board_id_index].gpio_num == -1) {
+		/* Suspend to RAM is not supported */
+		return SUSPEND_WAKEUP_DISABLED;
+	} else if (board_gpio[board_id_index].gpio_num == -2) {
+		/*
+		 * Suspend to RAM is supported but GPIO indication is
+		 * not implemented - Skip
+		 */
+		return SUSPEND_WAKEUP_ENABLED;
+	} else {
+		gpio = board_gpio[board_id_index].gpio_num;
+	}
+
+	/* Initialize MPP for GPIO (set MPP = 0x0) */
+	reg = reg_read(MPP_CONTROL_REG(MPP_REG_NUM(gpio)));
+	/* reset MPP21 to 0x0, keep rest of MPP settings*/
+	reg &= ~MPP_MASK(gpio);
+	reg_write(MPP_CONTROL_REG(MPP_REG_NUM(gpio)), reg);
+
+	/* Initialize GPIO as input */
+	reg = reg_read(GPP_DATA_OUT_EN_REG(GPP_REG_NUM(gpio)));
+	reg |= GPP_MASK(gpio);
+	reg_write(GPP_DATA_OUT_EN_REG(GPP_REG_NUM(gpio)), reg);
+
+	/*
+	 * Check GPP for input status from PIC: 0 - regular init,
+	 * 1 - suspend wakeup
+	 */
+	reg = reg_read(GPP_DATA_IN_REG(GPP_REG_NUM(gpio)));
+
+	/* if GPIO is ON: wakeup from S2RAM indication detected */
+	return (reg & GPP_MASK(gpio)) ? SUSPEND_WAKEUP_ENABLED_GPIO_DETECTED :
+		SUSPEND_WAKEUP_DISABLED;
+}
+
+/*
+ * get bit mask of enabled cs
+ * return bit mask of enabled cs:
+ * 1 - only cs0 enabled,
+ * 3 - both cs0 and cs1 enabled
+ */
+u32 mv_ddr_sys_env_get_cs_ena_from_reg(void)
+{
+	return reg_read(DDR3_RANK_CTRL_REG) &
+		((CS_EXIST_MASK << CS_EXIST_OFFS(0)) |
+		 (CS_EXIST_MASK << CS_EXIST_OFFS(1)) |
+		 (CS_EXIST_MASK << CS_EXIST_OFFS(2)) |
+		 (CS_EXIST_MASK << CS_EXIST_OFFS(3)));
+}
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.h b/drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.h
new file mode 100644
index 000000000000..229f2f10352e
--- /dev/null
+++ b/drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#ifndef _MV_DDR_SYS_ENV_LIB_H
+#define _MV_DDR_SYS_ENV_LIB_H
+
+#include "ddr_ml_wrapper.h"
+
+/* device revision */
+#define DEV_ID_REG			0x18238
+#define DEV_VERSION_ID_REG		0x1823c
+#define REVISON_ID_OFFS			8
+#define REVISON_ID_MASK			0xf00
+
+#define MPP_CONTROL_REG(id)		(0x18000 + (id * 4))
+#define GPP_DATA_OUT_REG(grp)		(MV_GPP_REGS_BASE(grp) + 0x00)
+#define GPP_DATA_OUT_EN_REG(grp)	(MV_GPP_REGS_BASE(grp) + 0x04)
+#define GPP_DATA_IN_REG(grp)		(MV_GPP_REGS_BASE(grp) + 0x10)
+#define MV_GPP_REGS_BASE(unit)		(0x18100 + ((unit) * 0x40))
+
+#define MPP_REG_NUM(GPIO_NUM)		(GPIO_NUM / 8)
+#define MPP_MASK(GPIO_NUM)		(0xf << 4 * (GPIO_NUM - \
+					(MPP_REG_NUM(GPIO_NUM) * 8)));
+#define GPP_REG_NUM(GPIO_NUM)		(GPIO_NUM / 32)
+#define GPP_MASK(GPIO_NUM)		(1 << GPIO_NUM % 32)
+
+/* device ID */
+/* Board ID numbers */
+#define MARVELL_BOARD_ID_MASK		0x10
+
+/* Customer boards for A38x */
+#define A38X_CUSTOMER_BOARD_ID_BASE	0x0
+#define A38X_CUSTOMER_BOARD_ID0		(A38X_CUSTOMER_BOARD_ID_BASE + 0)
+#define A38X_CUSTOMER_BOARD_ID1		(A38X_CUSTOMER_BOARD_ID_BASE + 1)
+#define A38X_MV_MAX_CUSTOMER_BOARD_ID	(A38X_CUSTOMER_BOARD_ID_BASE + 2)
+#define A38X_MV_CUSTOMER_BOARD_NUM	(A38X_MV_MAX_CUSTOMER_BOARD_ID - \
+					 A38X_CUSTOMER_BOARD_ID_BASE)
+
+/* Marvell boards for A38x */
+#define A38X_MARVELL_BOARD_ID_BASE	0x10
+#define RD_NAS_68XX_ID			(A38X_MARVELL_BOARD_ID_BASE + 0)
+#define DB_68XX_ID			(A38X_MARVELL_BOARD_ID_BASE + 1)
+#define RD_AP_68XX_ID			(A38X_MARVELL_BOARD_ID_BASE + 2)
+#define DB_AP_68XX_ID			(A38X_MARVELL_BOARD_ID_BASE + 3)
+#define DB_GP_68XX_ID			(A38X_MARVELL_BOARD_ID_BASE + 4)
+#define DB_BP_6821_ID			(A38X_MARVELL_BOARD_ID_BASE + 5)
+#define DB_AMC_6820_ID			(A38X_MARVELL_BOARD_ID_BASE + 6)
+#define A38X_MV_MAX_MARVELL_BOARD_ID	(A38X_MARVELL_BOARD_ID_BASE + 7)
+#define A38X_MV_MARVELL_BOARD_NUM	(A38X_MV_MAX_MARVELL_BOARD_ID - \
+					 A38X_MARVELL_BOARD_ID_BASE)
+
+/* Marvell boards for A39x */
+#define A39X_MARVELL_BOARD_ID_BASE	0x30
+#define A39X_DB_69XX_ID			(A39X_MARVELL_BOARD_ID_BASE + 0)
+#define A39X_RD_69XX_ID			(A39X_MARVELL_BOARD_ID_BASE + 1)
+#define A39X_MV_MAX_MARVELL_BOARD_ID	(A39X_MARVELL_BOARD_ID_BASE + 2)
+#define A39X_MV_MARVELL_BOARD_NUM	(A39X_MV_MAX_MARVELL_BOARD_ID - \
+					 A39X_MARVELL_BOARD_ID_BASE)
+
+struct board_wakeup_gpio {
+	u32 board_id;
+	int gpio_num;
+};
+
+enum suspend_wakeup_status {
+	SUSPEND_WAKEUP_DISABLED,
+	SUSPEND_WAKEUP_ENABLED,
+	SUSPEND_WAKEUP_ENABLED_GPIO_DETECTED,
+};
+
+/*
+ * GPIO status indication for Suspend Wakeup:
+ * If suspend to RAM is supported and GPIO inidcation is implemented,
+ * set the gpio number
+ * If suspend to RAM is supported but GPIO indication is not implemented
+ * set '-2'
+ * If suspend to RAM is not supported set '-1'
+ */
+#ifdef CONFIG_CUSTOMER_BOARD_SUPPORT
+#ifdef CONFIG_ARMADA_38X
+#define MV_BOARD_WAKEUP_GPIO_INFO {		\
+	{A38X_CUSTOMER_BOARD_ID0,	-1 },	\
+	{A38X_CUSTOMER_BOARD_ID0,	-1 },	\
+};
+#else
+#define MV_BOARD_WAKEUP_GPIO_INFO {		\
+	{A39X_CUSTOMER_BOARD_ID0,	-1 },	\
+	{A39X_CUSTOMER_BOARD_ID0,	-1 },	\
+};
+#endif /* CONFIG_ARMADA_38X */
+
+#else
+
+#ifdef CONFIG_ARMADA_38X
+#define MV_BOARD_WAKEUP_GPIO_INFO {	\
+	{RD_NAS_68XX_ID, -2 },		\
+	{DB_68XX_ID,	 -1 },		\
+	{RD_AP_68XX_ID,	 -2 },		\
+	{DB_AP_68XX_ID,	 -2 },		\
+	{DB_GP_68XX_ID,	 -2 },		\
+	{DB_BP_6821_ID,	 -2 },		\
+	{DB_AMC_6820_ID, -2 },		\
+};
+#else
+#define MV_BOARD_WAKEUP_GPIO_INFO {	\
+	{A39X_RD_69XX_ID, -1 },		\
+	{A39X_DB_69XX_ID, -1 },		\
+};
+#endif /* CONFIG_ARMADA_38X */
+#endif /* CONFIG_CUSTOMER_BOARD_SUPPORT */
+
+enum suspend_wakeup_status mv_ddr_sys_env_suspend_wakeup_check(void);
+u32 mv_ddr_sys_env_get_cs_ena_from_reg(void);
+
+#endif /* _MV_DDR_SYS_ENV_LIB_H */
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_topology.c b/drivers/ddr/marvell/a38x/mv_ddr_topology.c
new file mode 100644
index 000000000000..e82f35275061
--- /dev/null
+++ b/drivers/ddr/marvell/a38x/mv_ddr_topology.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#include "mv_ddr_topology.h"
+#include "mv_ddr_common.h"
+#include "mv_ddr_spd.h"
+#include "ddr3_init.h"
+#include "ddr_topology_def.h"
+#include "ddr3_training_ip_db.h"
+#include "ddr3_training_ip.h"
+
+
+unsigned int mv_ddr_cl_calc(unsigned int taa_min, unsigned int tclk)
+{
+	unsigned int cl = ceil_div(taa_min, tclk);
+
+	return mv_ddr_spd_supported_cl_get(cl);
+
+}
+
+unsigned int mv_ddr_cwl_calc(unsigned int tclk)
+{
+	unsigned int cwl;
+
+	if (tclk >= 1250)
+		cwl = 9;
+	else if (tclk >= 1071)
+		cwl = 10;
+	else if (tclk >= 938)
+		cwl = 11;
+	else if (tclk >= 833)
+		cwl = 12;
+	else
+		cwl = 0;
+
+	return cwl;
+}
+
+struct mv_ddr_topology_map *mv_ddr_topology_map_update(void)
+{
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+	unsigned int octets_per_if_num = ddr3_tip_dev_attr_get(0, MV_ATTR_OCTET_PER_INTERFACE);
+	enum hws_speed_bin speed_bin_index;
+	enum hws_ddr_freq freq = DDR_FREQ_LAST;
+	unsigned int tclk;
+	unsigned char val = 0;
+	int i;
+
+
+	if (tm->interface_params[0].memory_freq == DDR_FREQ_SAR)
+		tm->interface_params[0].memory_freq = mv_ddr_init_freq_get();
+
+	if (tm->cfg_src == MV_DDR_CFG_SPD) {
+		/* check dram device type */
+		val = mv_ddr_spd_dev_type_get(&tm->spd_data);
+		if (val != MV_DDR_SPD_DEV_TYPE_DDR4) {
+			printf("mv_ddr: unsupported dram device type found\n");
+			return NULL;
+		}
+
+		/* update topology map with timing data */
+		if (mv_ddr_spd_timing_calc(&tm->spd_data, tm->timing_data) > 0) {
+			printf("mv_ddr: negative timing data found\n");
+			return NULL;
+		}
+
+		/* update device width in topology map */
+		tm->interface_params[0].bus_width = mv_ddr_spd_dev_width_get(&tm->spd_data);
+
+		/* update die capacity in topology map */
+		tm->interface_params[0].memory_size = mv_ddr_spd_die_capacity_get(&tm->spd_data);
+
+		/* update bus bit mask in topology map */
+		tm->bus_act_mask = mv_ddr_bus_bit_mask_get();
+
+		/* update cs bit mask in topology map */
+		val = mv_ddr_spd_cs_bit_mask_get(&tm->spd_data);
+		for (i = 0; i < octets_per_if_num; i++) {
+				tm->interface_params[0].as_bus_params[i].cs_bitmask = val;
+		}
+
+		/* check dram module type */
+		val = mv_ddr_spd_module_type_get(&tm->spd_data);
+		switch (val) {
+		case MV_DDR_SPD_MODULE_TYPE_UDIMM:
+		case MV_DDR_SPD_MODULE_TYPE_SO_DIMM:
+		case MV_DDR_SPD_MODULE_TYPE_MINI_UDIMM:
+		case MV_DDR_SPD_MODULE_TYPE_72BIT_SO_UDIMM:
+		case MV_DDR_SPD_MODULE_TYPE_16BIT_SO_DIMM:
+		case MV_DDR_SPD_MODULE_TYPE_32BIT_SO_DIMM:
+			break;
+		default:
+			printf("mv_ddr: unsupported dram module type found\n");
+			return NULL;
+		}
+
+		/* update mirror bit mask in topology map */
+		val = mv_ddr_spd_mem_mirror_get(&tm->spd_data);
+		for (i = 0; i < octets_per_if_num; i++) {
+				tm->interface_params[0].as_bus_params[i].mirror_enable_bitmask = val << 1;
+		}
+
+		tclk = 1000000 / freq_val[tm->interface_params[0].memory_freq];
+		/* update cas write latency (cwl) */
+		val = mv_ddr_cwl_calc(tclk);
+		if (val == 0) {
+			printf("mv_ddr: unsupported cas write latency value found\n");
+			return NULL;
+		}
+		tm->interface_params[0].cas_wl = val;
+
+		/* update cas latency (cl) */
+		mv_ddr_spd_supported_cls_calc(&tm->spd_data);
+		val = mv_ddr_cl_calc(tm->timing_data[MV_DDR_TAA_MIN], tclk);
+		if (val == 0) {
+			printf("mv_ddr: unsupported cas latency value found\n");
+			return NULL;
+		}
+		tm->interface_params[0].cas_l = val;
+	} else if (tm->cfg_src == MV_DDR_CFG_DEFAULT) {
+		/* set cas and cas-write latencies per speed bin, if they unset */
+		speed_bin_index = tm->interface_params[0].speed_bin_index;
+		freq = tm->interface_params[0].memory_freq;
+
+		if (tm->interface_params[0].cas_l == 0)
+			tm->interface_params[0].cas_l =
+				cas_latency_table[speed_bin_index].cl_val[freq];
+
+		if (tm->interface_params[0].cas_wl == 0)
+			tm->interface_params[0].cas_wl =
+				cas_write_latency_table[speed_bin_index].cl_val[freq];
+	}
+
+
+	return tm;
+}
+
+unsigned short mv_ddr_bus_bit_mask_get(void)
+{
+	unsigned short pri_and_ext_bus_width = 0x0;
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+	unsigned int octets_per_if_num = ddr3_tip_dev_attr_get(0, MV_ATTR_OCTET_PER_INTERFACE);
+
+	if (tm->cfg_src == MV_DDR_CFG_SPD) {
+		enum mv_ddr_pri_bus_width pri_bus_width = mv_ddr_spd_pri_bus_width_get(&tm->spd_data);
+		enum mv_ddr_bus_width_ext bus_width_ext = mv_ddr_spd_bus_width_ext_get(&tm->spd_data);
+
+		switch (pri_bus_width) {
+		case MV_DDR_PRI_BUS_WIDTH_16:
+			pri_and_ext_bus_width = BUS_MASK_16BIT;
+			break;
+		case MV_DDR_PRI_BUS_WIDTH_32:
+			pri_and_ext_bus_width = BUS_MASK_32BIT;
+			break;
+		case MV_DDR_PRI_BUS_WIDTH_64:
+			pri_and_ext_bus_width = MV_DDR_64BIT_BUS_MASK;
+			break;
+		default:
+			pri_and_ext_bus_width = 0x0;
+		}
+
+		if (bus_width_ext == MV_DDR_BUS_WIDTH_EXT_8)
+			pri_and_ext_bus_width |= 1 << (octets_per_if_num - 1);
+	}
+
+	return pri_and_ext_bus_width;
+}
+
+unsigned int mv_ddr_if_bus_width_get(void)
+{
+	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+	unsigned int bus_width;
+
+	switch (tm->bus_act_mask) {
+	case BUS_MASK_16BIT:
+	case BUS_MASK_16BIT_ECC:
+	case BUS_MASK_16BIT_ECC_PUP3:
+		bus_width = 16;
+		break;
+	case BUS_MASK_32BIT:
+	case BUS_MASK_32BIT_ECC:
+	case MV_DDR_32BIT_ECC_PUP8_BUS_MASK:
+		bus_width = 32;
+		break;
+	case MV_DDR_64BIT_BUS_MASK:
+	case MV_DDR_64BIT_ECC_PUP8_BUS_MASK:
+		bus_width = 64;
+		break;
+	default:
+		printf("mv_ddr: unsupported bus active mask parameter found\n");
+		bus_width = 0;
+	}
+
+	return bus_width;
+}
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_topology.h b/drivers/ddr/marvell/a38x/mv_ddr_topology.h
new file mode 100644
index 000000000000..9fd5019ff235
--- /dev/null
+++ b/drivers/ddr/marvell/a38x/mv_ddr_topology.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#ifndef _MV_DDR_TOPOLOGY_H
+#define _MV_DDR_TOPOLOGY_H
+
+/* ddr bus masks */
+#define BUS_MASK_32BIT			0xf
+#define BUS_MASK_32BIT_ECC		0x1f
+#define BUS_MASK_16BIT			0x3
+#define BUS_MASK_16BIT_ECC		0x13
+#define BUS_MASK_16BIT_ECC_PUP3		0xb
+#define MV_DDR_64BIT_BUS_MASK		0xff
+#define MV_DDR_64BIT_ECC_PUP8_BUS_MASK	0x1ff
+#define MV_DDR_32BIT_ECC_PUP8_BUS_MASK	0x10f
+
+/* source of ddr configuration data */
+enum mv_ddr_cfg_src {
+	MV_DDR_CFG_DEFAULT,	/* based on data in mv_ddr_topology_map structure */
+	MV_DDR_CFG_SPD,		/* based on data in spd */
+	MV_DDR_CFG_USER,	/* based on data from user */
+	MV_DDR_CFG_STATIC,	/* based on data from user in register-value format */
+	MV_DDR_CFG_LAST
+};
+
+enum mv_ddr_num_of_sub_phys_per_ddr_unit {
+	SINGLE_SUB_PHY = 1,
+	TWO_SUB_PHYS = 2
+};
+
+enum mv_ddr_temperature {
+	MV_DDR_TEMP_LOW,
+	MV_DDR_TEMP_NORMAL,
+	MV_DDR_TEMP_HIGH
+};
+
+enum mv_ddr_timing_data {
+	MV_DDR_TCK_AVG_MIN, /* sdram min cycle time (t ck avg min) */
+	MV_DDR_TAA_MIN, /* min cas latency time (t aa min) */
+	MV_DDR_TRFC1_MIN, /* min refresh recovery delay time (t rfc1 min) */
+	MV_DDR_TWR_MIN, /* min write recovery time (t wr min) */
+	MV_DDR_TRCD_MIN, /* min ras to cas delay time (t rcd min) */
+	MV_DDR_TRP_MIN, /* min row precharge delay time (t rp min) */
+	MV_DDR_TRC_MIN, /* min active to active/refresh delay time (t rc min) */
+	MV_DDR_TRAS_MIN, /* min active to precharge delay time (t ras min) */
+	MV_DDR_TRRD_S_MIN, /* min activate to activate delay time (t rrd_s min), diff bank group */
+	MV_DDR_TRRD_L_MIN, /* min activate to activate delay time (t rrd_l min), same bank group */
+	MV_DDR_TFAW_MIN, /* min four activate window delay time (t faw min) */
+	MV_DDR_TWTR_S_MIN, /* min write to read time (t wtr s min), diff bank group */
+	MV_DDR_TWTR_L_MIN, /* min write to read time (t wtr l min), same bank group */
+	MV_DDR_TDATA_LAST
+};
+
+enum mv_ddr_dev_width { /* sdram device width */
+	MV_DDR_DEV_WIDTH_4BIT,
+	MV_DDR_DEV_WIDTH_8BIT,
+	MV_DDR_DEV_WIDTH_16BIT,
+	MV_DDR_DEV_WIDTH_32BIT,
+	MV_DDR_DEV_WIDTH_LAST
+};
+
+enum mv_ddr_die_capacity { /* total sdram capacity per die, megabits */
+	MV_DDR_DIE_CAP_256MBIT,
+	MV_DDR_DIE_CAP_512MBIT = 0,
+	MV_DDR_DIE_CAP_1GBIT,
+	MV_DDR_DIE_CAP_2GBIT,
+	MV_DDR_DIE_CAP_4GBIT,
+	MV_DDR_DIE_CAP_8GBIT,
+	MV_DDR_DIE_CAP_16GBIT,
+	MV_DDR_DIE_CAP_32GBIT,
+	MV_DDR_DIE_CAP_12GBIT,
+	MV_DDR_DIE_CAP_24GBIT,
+	MV_DDR_DIE_CAP_LAST
+};
+
+enum mv_ddr_pkg_rank { /* number of package ranks per dimm */
+	MV_DDR_PKG_RANK_1,
+	MV_DDR_PKG_RANK_2,
+	MV_DDR_PKG_RANK_3,
+	MV_DDR_PKG_RANK_4,
+	MV_DDR_PKG_RANK_5,
+	MV_DDR_PKG_RANK_6,
+	MV_DDR_PKG_RANK_7,
+	MV_DDR_PKG_RANK_8,
+	MV_DDR_PKG_RANK_LAST
+};
+
+enum mv_ddr_pri_bus_width { /* number of primary bus width bits */
+	MV_DDR_PRI_BUS_WIDTH_8,
+	MV_DDR_PRI_BUS_WIDTH_16,
+	MV_DDR_PRI_BUS_WIDTH_32,
+	MV_DDR_PRI_BUS_WIDTH_64,
+	MV_DDR_PRI_BUS_WIDTH_LAST
+};
+
+enum mv_ddr_bus_width_ext { /* number of extension bus width bits */
+	MV_DDR_BUS_WIDTH_EXT_0,
+	MV_DDR_BUS_WIDTH_EXT_8,
+	MV_DDR_BUS_WIDTH_EXT_LAST
+};
+
+enum mv_ddr_die_count {
+	MV_DDR_DIE_CNT_1,
+	MV_DDR_DIE_CNT_2,
+	MV_DDR_DIE_CNT_3,
+	MV_DDR_DIE_CNT_4,
+	MV_DDR_DIE_CNT_5,
+	MV_DDR_DIE_CNT_6,
+	MV_DDR_DIE_CNT_7,
+	MV_DDR_DIE_CNT_8,
+	MV_DDR_DIE_CNT_LAST
+};
+
+unsigned int mv_ddr_cl_calc(unsigned int taa_min, unsigned int tclk);
+unsigned int mv_ddr_cwl_calc(unsigned int tclk);
+struct mv_ddr_topology_map *mv_ddr_topology_map_update(void);
+struct dram_config *mv_ddr_dram_config_update(void);
+unsigned short mv_ddr_bus_bit_mask_get(void);
+unsigned int mv_ddr_if_bus_width_get(void);
+
+#endif /* _MV_DDR_TOPOLOGY_H */
diff --git a/drivers/ddr/marvell/a38x/seq_exec.h b/drivers/ddr/marvell/a38x/seq_exec.h
new file mode 100644
index 000000000000..14f406a75f63
--- /dev/null
+++ b/drivers/ddr/marvell/a38x/seq_exec.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier:	GPL-2.0
+ */
+
+#ifndef _SEQ_EXEC_H
+#define _SEQ_EXEC_H
+
+#define NA			0xff
+#define DEFAULT_PARAM		0
+#define MV_BOARD_TCLK_ERROR	0xffffffff
+
+#define NO_DATA			0xffffffff
+#define MAX_DATA_ARRAY		5
+#define FIRST_CELL		0
+
+/* Operation types */
+enum mv_op {
+	WRITE_OP,
+	DELAY_OP,
+	POLL_OP,
+};
+
+/* Operation parameters */
+struct op_params {
+	u32 unit_base_reg;
+	u32 unit_offset;
+	u32 mask;
+	u32 data[MAX_DATA_ARRAY];	/* data array */
+	u8 wait_time;			/* msec */
+	u16 num_of_loops;		/* for polling only */
+};
+
+/*
+ * Sequence parameters. Each sequence contains:
+ * 1. Sequence id.
+ * 2. Sequence size (total amount of operations during the sequence)
+ * 3. a series of operations. operations can be write, poll or delay
+ * 4. index in the data array (the entry where the relevant data sits)
+ */
+struct cfg_seq {
+	struct op_params *op_params_ptr;
+	u8 cfg_seq_size;
+	u8 data_arr_idx;
+};
+
+extern struct cfg_seq serdes_seq_db[];
+
+/*
+ * A generic function type for executing an operation (write, poll or delay)
+ */
+typedef int (*op_execute_func_ptr)(u32 serdes_num, struct op_params *params,
+				   u32 data_arr_idx);
+
+/* Specific functions for executing each operation */
+int write_op_execute(u32 serdes_num, struct op_params *params,
+		     u32 data_arr_idx);
+int delay_op_execute(u32 serdes_num, struct op_params *params,
+		     u32 data_arr_idx);
+int poll_op_execute(u32 serdes_num, struct op_params *params, u32 data_arr_idx);
+enum mv_op get_cfg_seq_op(struct op_params *params);
+int mv_seq_exec(u32 serdes_num, u32 seq_id);
+
+#endif /*_SEQ_EXEC_H*/
diff --git a/drivers/ddr/marvell/a38x/silicon_if.h b/drivers/ddr/marvell/a38x/silicon_if.h
deleted file mode 100644
index 7fce27da1238..000000000000
--- a/drivers/ddr/marvell/a38x/silicon_if.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- *
- * SPDX-License-Identifier:	GPL-2.0
- */
-
-#ifndef __silicon_if_H
-#define __silicon_if_H
-
-/* max number of devices supported by driver */
-#ifdef CO_CPU_RUN
-#define HWS_MAX_DEVICE_NUM (1)
-#else
-#define HWS_MAX_DEVICE_NUM (16)
-#endif
-
-#endif /* __silicon_if_H */
diff --git a/drivers/ddr/marvell/a38x/xor.c b/drivers/ddr/marvell/a38x/xor.c
index 9c73c54eec54..368432165fa3 100644
--- a/drivers/ddr/marvell/a38x/xor.c
+++ b/drivers/ddr/marvell/a38x/xor.c
@@ -4,13 +4,6 @@
  * SPDX-License-Identifier:	GPL-2.0
  */
 
-#include <common.h>
-#include <i2c.h>
-#include <spl.h>
-#include <asm/io.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/soc.h>
-
 #include "ddr3_init.h"
 #include "xor_regs.h"
 
@@ -22,39 +15,48 @@
 #endif
 
 static u32 ui_xor_regs_ctrl_backup;
-static u32 ui_xor_regs_base_backup[MAX_CS];
-static u32 ui_xor_regs_mask_backup[MAX_CS];
+static u32 ui_xor_regs_base_backup[MAX_CS_NUM + 1];
+static u32 ui_xor_regs_mask_backup[MAX_CS_NUM + 1];
 
-void mv_sys_xor_init(u32 num_of_cs, u32 cs_ena, u32 cs_size, u32 base_delta)
+void mv_sys_xor_init(u32 num_of_cs, u32 cs_ena, uint64_t cs_size, u32 base_delta)
 {
-	u32 reg, ui, base, cs_count;
+	u32 reg, ui, cs_count;
+	uint64_t base, size_mask;
 
 	ui_xor_regs_ctrl_backup = reg_read(XOR_WINDOW_CTRL_REG(0, 0));
-	for (ui = 0; ui < MAX_CS; ui++)
+	for (ui = 0; ui < MAX_CS_NUM + 1; ui++)
 		ui_xor_regs_base_backup[ui] =
 			reg_read(XOR_BASE_ADDR_REG(0, ui));
-	for (ui = 0; ui < MAX_CS; ui++)
+	for (ui = 0; ui < MAX_CS_NUM + 1; ui++)
 		ui_xor_regs_mask_backup[ui] =
 			reg_read(XOR_SIZE_MASK_REG(0, ui));
 
 	reg = 0;
-	for (ui = 0; ui < (num_of_cs); ui++) {
-		/* Enable Window x for each CS */
-		reg |= (0x1 << (ui));
-		/* Enable Window x for each CS */
-		reg |= (0x3 << ((ui * 2) + 16));
+	for (ui = 0, cs_count = 0;
+	     (cs_count < num_of_cs) && (ui < 8);
+	     ui++, cs_count++) {
+		if (cs_ena & (1 << ui)) {
+			/* Enable Window x for each CS */
+			reg |= (0x1 << (ui));
+			/* Enable Window x for each CS */
+			reg |= (0x3 << ((ui * 2) + 16));
+		}
 	}
 
 	reg_write(XOR_WINDOW_CTRL_REG(0, 0), reg);
 
 	cs_count = 0;
-	for (ui = 0; ui < num_of_cs; ui++) {
+	for (ui = 0, cs_count = 0;
+	     (cs_count < num_of_cs) && (ui < 8);
+	     ui++, cs_count++) {
 		if (cs_ena & (1 << ui)) {
 			/*
 			 * window x - Base - 0x00000000,
 			 * Attribute 0x0e - DRAM
 			 */
 			base = cs_size * ui + base_delta;
+			/* fixed size 2GB for each CS */
+			size_mask = 0x7FFF0000;
 			switch (ui) {
 			case 0:
 				base |= 0xe00;
@@ -68,13 +70,19 @@ void mv_sys_xor_init(u32 num_of_cs, u32 cs_ena, u32 cs_size, u32 base_delta)
 			case 3:
 				base |= 0x700;
 				break;
+			case 4: /* SRAM */
+				base = 0x40000000;
+				/* configure as shared transaction */
+				base |= 0x1F00;
+				size_mask = 0xF0000;
+				break;
 			}
 
-			reg_write(XOR_BASE_ADDR_REG(0, cs_count), base);
-
+			reg_write(XOR_BASE_ADDR_REG(0, ui), (u32)base);
+			size_mask = (cs_size / _64K) - 1;
+			size_mask = (size_mask << XESMRX_SIZE_MASK_OFFS) & XESMRX_SIZE_MASK_MASK;
 			/* window x - Size */
-			reg_write(XOR_SIZE_MASK_REG(0, cs_count), 0x7fff0000);
-			cs_count++;
+			reg_write(XOR_SIZE_MASK_REG(0, ui), (u32)size_mask);
 		}
 	}
 
@@ -88,10 +96,10 @@ void mv_sys_xor_finish(void)
 	u32 ui;
 
 	reg_write(XOR_WINDOW_CTRL_REG(0, 0), ui_xor_regs_ctrl_backup);
-	for (ui = 0; ui < MAX_CS; ui++)
+	for (ui = 0; ui < MAX_CS_NUM + 1; ui++)
 		reg_write(XOR_BASE_ADDR_REG(0, ui),
 			  ui_xor_regs_base_backup[ui]);
-	for (ui = 0; ui < MAX_CS; ui++)
+	for (ui = 0; ui < MAX_CS_NUM + 1; ui++)
 		reg_write(XOR_SIZE_MASK_REG(0, ui),
 			  ui_xor_regs_mask_backup[ui]);
 
@@ -154,11 +162,14 @@ int mv_xor_ctrl_set(u32 chan, u32 xor_ctrl)
 	return MV_OK;
 }
 
-int mv_xor_mem_init(u32 chan, u32 start_ptr, u32 block_size,
+int mv_xor_mem_init(u32 chan, u32 start_ptr, unsigned long long block_size,
 		    u32 init_val_high, u32 init_val_low)
 {
 	u32 temp;
 
+	if (block_size == _4G)
+		block_size -= 1;
+
 	/* Parameter checking */
 	if (chan >= MV_XOR_MAX_CHAN)
 		return MV_BAD_PARAM;
@@ -329,28 +340,123 @@ void ddr3_new_tip_ecc_scrub(void)
 {
 	u32 cs_c, max_cs;
 	u32 cs_ena = 0;
+	u32 dev_num = 0;
+	uint64_t total_mem_size, cs_mem_size = 0;
 
-	printf("DDR3 Training Sequence - Start scrubbing\n");
-
-	max_cs = hws_ddr3_tip_max_cs_get();
+	printf("DDR Training Sequence - Start scrubbing\n");
+	max_cs = ddr3_tip_max_cs_get(dev_num);
 	for (cs_c = 0; cs_c < max_cs; cs_c++)
 		cs_ena |= 1 << cs_c;
 
-	mv_sys_xor_init(max_cs, cs_ena, 0x80000000, 0);
-
-	mv_xor_mem_init(0, 0x00000000, 0x80000000, 0xdeadbeef, 0xdeadbeef);
-	/* wait for previous transfer completion */
-	while (mv_xor_state_get(0) != MV_IDLE)
-		;
-
-	mv_xor_mem_init(0, 0x80000000, 0x40000000, 0xdeadbeef, 0xdeadbeef);
-
+	mv_sys_xor_init(max_cs, cs_ena, cs_mem_size, 0);
+	total_mem_size = max_cs * cs_mem_size;
+	mv_xor_mem_init(0, 0, total_mem_size, 0xdeadbeef, 0xdeadbeef);
 	/* wait for previous transfer completion */
 	while (mv_xor_state_get(0) != MV_IDLE)
 		;
-
 	/* Return XOR State */
 	mv_sys_xor_finish();
 
 	printf("DDR3 Training Sequence - End scrubbing\n");
 }
+
+/*
+* mv_xor_transfer - Transfer data from source to destination in one of
+*		    three modes: XOR, CRC32 or DMA
+*
+* DESCRIPTION:
+*	This function initiates XOR channel, according to function parameters,
+*	in order to perform XOR, CRC32 or DMA transaction.
+*	To gain maximum performance the user is asked to keep the following
+*	restrictions:
+*	1) Selected engine is available (not busy).
+*	2) This module does not take into consideration CPU MMU issues.
+*	   In order for the XOR engine to access the appropriate source
+*	   and destination, address parameters must be given in system
+*	   physical mode.
+*	3) This API does not take care of cache coherency issues. The source,
+*	   destination and, in case of chain, the descriptor list are assumed
+*	   to be cache coherent.
+*	4) Parameters validity.
+*
+* INPUT:
+*	chan		- XOR channel number.
+*	type	- One of three: XOR, CRC32 and DMA operations.
+*	xor_chain_ptr	- address of chain pointer
+*
+* OUTPUT:
+*	None.
+*
+* RETURN:
+*       MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
+*
+*******************************************************************************/
+int mv_xor_transfer(u32 chan, enum xor_type type, u32 xor_chain_ptr)
+{
+	u32 temp;
+
+	/* Parameter checking */
+	if (chan >= MV_XOR_MAX_CHAN) {
+		DB(printf("%s: ERR. Invalid chan num %d\n", __func__, chan));
+		return MV_BAD_PARAM;
+	}
+	if (mv_xor_state_get(chan) == MV_ACTIVE) {
+		DB(printf("%s: ERR. Channel is already active\n", __func__));
+		return MV_BUSY;
+	}
+	if (xor_chain_ptr == 0x0) {
+		DB(printf("%s: ERR. xor_chain_ptr is NULL pointer\n", __func__));
+		return MV_BAD_PARAM;
+	}
+
+	/* read configuration register and mask the operation mode field */
+	temp = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
+	temp &= ~XEXCR_OPERATION_MODE_MASK;
+
+	switch (type) {
+	case MV_XOR:
+		if ((xor_chain_ptr & XEXDPR_DST_PTR_XOR_MASK) != 0) {
+			DB(printf("%s: ERR. Invalid chain pointer (bits [5:0] must be cleared)\n",
+				  __func__));
+			return MV_BAD_PARAM;
+		}
+		/* set the operation mode to XOR */
+		temp |= XEXCR_OPERATION_MODE_XOR;
+		break;
+	case MV_DMA:
+		if ((xor_chain_ptr & XEXDPR_DST_PTR_DMA_MASK) != 0) {
+			DB(printf("%s: ERR. Invalid chain pointer (bits [4:0] must be cleared)\n",
+				  __func__));
+			return MV_BAD_PARAM;
+		}
+		/* set the operation mode to DMA */
+		temp |= XEXCR_OPERATION_MODE_DMA;
+		break;
+	case MV_CRC32:
+		if ((xor_chain_ptr & XEXDPR_DST_PTR_CRC_MASK) != 0) {
+			DB(printf("%s: ERR. Invalid chain pointer (bits [4:0] must be cleared)\n",
+				  __func__));
+			return MV_BAD_PARAM;
+		}
+		/* set the operation mode to CRC32 */
+		temp |= XEXCR_OPERATION_MODE_CRC;
+		break;
+	default:
+		return MV_BAD_PARAM;
+	}
+
+	/* write the operation mode to the register */
+	reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), temp);
+	/*
+	 * update the NextDescPtr field in the XOR Engine [0..1] Next Descriptor
+	 * Pointer Register (XExNDPR)
+	 */
+	reg_write(XOR_NEXT_DESC_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
+		  xor_chain_ptr);
+
+	/* start transfer */
+	reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
+		    XEXACTR_XESTART_MASK);
+
+	return MV_OK;
+}
diff --git a/drivers/ddr/marvell/a38x/xor.h b/drivers/ddr/marvell/a38x/xor.h
index 7b1e3161772c..f389769409a1 100644
--- a/drivers/ddr/marvell/a38x/xor.h
+++ b/drivers/ddr/marvell/a38x/xor.h
@@ -9,8 +9,6 @@
 
 #define SRAM_BASE		0x40000000
 
-#include "ddr3_hws_hw_training_def.h"
-
 #define MV_XOR_MAX_UNIT		2	/* XOR unit == XOR engine */
 #define MV_XOR_MAX_CHAN		4	/* total channels for all units */
 #define MV_XOR_MAX_CHAN_PER_UNIT 2	/* channels for units */
@@ -88,5 +86,6 @@ int mv_xor_ctrl_set(u32 chan, u32 xor_ctrl);
 int mv_xor_command_set(u32 chan, enum mv_command command);
 int mv_xor_override_set(u32 chan, enum xor_override_target target, u32 win_num,
 			int enable);
+int mv_xor_transfer(u32 chan, enum xor_type type, u32 xor_chain_ptr);
 
 #endif
-- 
2.16.2

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH v2 5/6] ARM: mvebu: a38x: restore support for setting timing
  2018-04-09 10:12 [U-Boot] [PATCH v2 0/6] ARM: mvebu: a38x: updates to ddr training code Chris Packham
                   ` (3 preceding siblings ...)
  2018-04-09 10:12 ` [U-Boot] [PATCH v2 4/6] ARM: mvebu: a38x: sync ddr training code with upstream Chris Packham
@ 2018-04-09 10:12 ` Chris Packham
  2018-04-09 10:12 ` [U-Boot] [PATCH v2 6/6] ARM: mvebu: a38x: use non-zero size for ddr scrubbing Chris Packham
  2018-05-09 10:23 ` [U-Boot] [PATCH v2 0/6] ARM: mvebu: a38x: updates to ddr training code Stefan Roese
  6 siblings, 0 replies; 8+ messages in thread
From: Chris Packham @ 2018-04-09 10:12 UTC (permalink / raw)
  To: u-boot

This restores support for configuring the timing mode based on the
ddr_topology. This was originally implemented in commit 90bcc3d38d2b
("driver/ddr: Add support for setting timing in hws_topology_map") but
was removed as part of the upstream sync.

Signed-off-by: Chris Packham <judge.packham@gmail.com>
---

Changes in v2: New

 board/CZ.NIC/turris_omnia/turris_omnia.c      | 6 ++++--
 board/Marvell/db-88f6820-amc/db-88f6820-amc.c | 3 ++-
 board/Marvell/db-88f6820-gp/db-88f6820-gp.c   | 3 ++-
 board/gdsys/a38x/controlcenterdc.c            | 3 ++-
 board/solidrun/clearfog/clearfog.c            | 3 ++-
 drivers/ddr/marvell/a38x/ddr3_training.c      | 8 ++++++++
 drivers/ddr/marvell/a38x/ddr_topology_def.h   | 3 +++
 drivers/ddr/marvell/a38x/mv_ddr_plat.c        | 5 -----
 drivers/ddr/marvell/a38x/mv_ddr_topology.h    | 6 ++++++
 9 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/board/CZ.NIC/turris_omnia/turris_omnia.c b/board/CZ.NIC/turris_omnia/turris_omnia.c
index 9477a802acde..3535e30e3ed9 100644
--- a/board/CZ.NIC/turris_omnia/turris_omnia.c
+++ b/board/CZ.NIC/turris_omnia/turris_omnia.c
@@ -214,7 +214,8 @@ static struct mv_ddr_topology_map board_topology_map_1g = {
 	    MV_DDR_DIE_CAP_4GBIT,			/* mem_size */
 	    DDR_FREQ_800,		/* frequency */
 	    0, 0,			/* cas_wl cas_l */
-	    MV_DDR_TEMP_NORMAL} },	/* temperature */
+	    MV_DDR_TEMP_NORMAL,		/* temperature */
+	    MV_DDR_TIM_2T} },		/* timing */
 	BUS_MASK_32BIT,			/* Busses mask */
 	MV_DDR_CFG_DEFAULT,		/* ddr configuration data source */
 	{ {0} },			/* raw spd data */
@@ -235,7 +236,8 @@ static struct mv_ddr_topology_map board_topology_map_2g = {
 	    MV_DDR_DIE_CAP_8GBIT,			/* mem_size */
 	    DDR_FREQ_800,		/* frequency */
 	    0, 0,			/* cas_wl cas_l */
-	    MV_DDR_TEMP_NORMAL} },	/* temperature */
+	    MV_DDR_TEMP_NORMAL,		/* temperature */
+	    MV_DDR_TIM_2T} },		/* timing */
 	BUS_MASK_32BIT,			/* Busses mask */
 	MV_DDR_CFG_DEFAULT,		/* ddr configuration data source */
 	{ {0} },			/* raw spd data */
diff --git a/board/Marvell/db-88f6820-amc/db-88f6820-amc.c b/board/Marvell/db-88f6820-amc/db-88f6820-amc.c
index 2a092cb80418..aeb617172163 100644
--- a/board/Marvell/db-88f6820-amc/db-88f6820-amc.c
+++ b/board/Marvell/db-88f6820-amc/db-88f6820-amc.c
@@ -70,7 +70,8 @@ static struct mv_ddr_topology_map board_topology_map = {
 	    MV_DDR_DIE_CAP_2GBIT,	/* mem_size */
 	    DDR_FREQ_800,		/* frequency */
 	    0, 0,			/* cas_wl cas_l */
-	    MV_DDR_TEMP_LOW} },		/* temperature */
+	    MV_DDR_TEMP_LOW,		/* temperature */
+	    MV_DDR_TIM_DEFAULT} },	/* timing */
 	BUS_MASK_32BIT,			/* Busses mask */
 	MV_DDR_CFG_DEFAULT,		/* ddr configuration data source */
 	{ {0} },			/* raw spd data */
diff --git a/board/Marvell/db-88f6820-gp/db-88f6820-gp.c b/board/Marvell/db-88f6820-gp/db-88f6820-gp.c
index e3b6f2d8a7e6..073b5388080a 100644
--- a/board/Marvell/db-88f6820-gp/db-88f6820-gp.c
+++ b/board/Marvell/db-88f6820-gp/db-88f6820-gp.c
@@ -91,7 +91,8 @@ static struct mv_ddr_topology_map board_topology_map = {
 	    MV_DDR_DIE_CAP_4GBIT,	/* mem_size */
 	    DDR_FREQ_800,		/* frequency */
 	    0, 0,			/* cas_wl cas_l */
-	    MV_DDR_TEMP_LOW} },		/* temperature */
+	    MV_DDR_TEMP_LOW,		/* temperature */
+	    MV_DDR_TIM_DEFAULT} },	/* timing */
 	BUS_MASK_32BIT,			/* Busses mask */
 	MV_DDR_CFG_DEFAULT,		/* ddr configuration data source */
 	{ {0} },			/* raw spd data */
diff --git a/board/gdsys/a38x/controlcenterdc.c b/board/gdsys/a38x/controlcenterdc.c
index 1b3b881c3996..0ad6825f3057 100644
--- a/board/gdsys/a38x/controlcenterdc.c
+++ b/board/gdsys/a38x/controlcenterdc.c
@@ -54,7 +54,8 @@ static struct mv_ddr_topology_map ddr_topology_map = {
 	    MV_DDR_DIE_CAP_4GBIT,	/* mem_size */
 	    DDR_FREQ_533,		/* frequency */
 	    0, 0,			/* cas_wl cas_l */
-	    MV_DDR_TEMP_LOW} },		/* temperature */
+	    MV_DDR_TEMP_LOW,		/* temperature */
+	    MV_DDR_TIM_DEFAULT} },	/* timing */
 	BUS_MASK_32BIT,			/* Busses mask */
 	MV_DDR_CFG_DEFAULT,		/* ddr configuration data source */
 	{ {0} },			/* raw spd data */
diff --git a/board/solidrun/clearfog/clearfog.c b/board/solidrun/clearfog/clearfog.c
index 75eb59ae3ee3..901a558a90ac 100644
--- a/board/solidrun/clearfog/clearfog.c
+++ b/board/solidrun/clearfog/clearfog.c
@@ -84,7 +84,8 @@ static struct mv_ddr_topology_map board_topology_map = {
 	    MV_DDR_DIE_CAP_4GBIT,	/* mem_size */
 	    DDR_FREQ_800,		/* frequency */
 	    0, 0,			/* cas_wl cas_l */
-	    MV_DDR_TEMP_LOW} },		/* temperature */
+	    MV_DDR_TEMP_LOW,		/* temperature */
+	    MV_DDR_TIM_DEFAULT} },	/* timing */
 	BUS_MASK_32BIT,			/* Busses mask */
 	MV_DDR_CFG_DEFAULT,		/* ddr configuration data source */
 	{ {0} },			/* raw spd data */
diff --git a/drivers/ddr/marvell/a38x/ddr3_training.c b/drivers/ddr/marvell/a38x/ddr3_training.c
index 0b414aba1fda..f65ff4db4ceb 100644
--- a/drivers/ddr/marvell/a38x/ddr3_training.c
+++ b/drivers/ddr/marvell/a38x/ddr3_training.c
@@ -366,6 +366,7 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_
 	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
 	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 	enum hws_ddr_freq freq = tm->interface_params[0].memory_freq;
+	enum mv_ddr_timing timing;
 
 	DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
 			  ("Init_controller, do_mrs_phy=%d, is_ctrl64_bit=%d\n",
@@ -604,8 +605,12 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_
 				      DUNIT_CTRL_HIGH_REG,
 				      (init_cntr_prm->msys_init << 7), (1 << 7)));
 
+			timing = tm->interface_params[if_id].timing;
+
 			if (mode_2t != 0xff) {
 				t2t = mode_2t;
+			} else if (timing != MV_DDR_TIM_DEFAULT) {
+				t2t = (timing == MV_DDR_TIM_2T) ? 1 : 0;
 			} else {
 				/* calculate number of CS (per interface) */
 				CHECK_STATUS(calc_cs_num
@@ -1269,6 +1274,7 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type,
 	u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
 	struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 	unsigned int tclk;
+	enum mv_ddr_timing timing = tm->interface_params[if_id].timing;
 
 	DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
 			  ("dev %d access %d IF %d freq %d\n", dev_num,
@@ -1411,6 +1417,8 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type,
 		/* Calculate 2T mode */
 		if (mode_2t != 0xff) {
 			t2t = mode_2t;
+		} else if (timing != MV_DDR_TIM_DEFAULT) {
+			t2t = (timing == MV_DDR_TIM_2T) ? 1 : 0;
 		} else {
 			/* Calculate number of CS per interface */
 			CHECK_STATUS(calc_cs_num(dev_num, if_id, &cs_num));
diff --git a/drivers/ddr/marvell/a38x/ddr_topology_def.h b/drivers/ddr/marvell/a38x/ddr_topology_def.h
index 8fd0361dfbd4..b7f09fc53a75 100644
--- a/drivers/ddr/marvell/a38x/ddr_topology_def.h
+++ b/drivers/ddr/marvell/a38x/ddr_topology_def.h
@@ -65,6 +65,9 @@ struct if_params {
 
 	/* operation temperature */
 	enum mv_ddr_temperature interface_temp;
+
+	/* 2T vs 1T mode (by default computed from number of CSs) */
+	enum mv_ddr_timing timing;
 };
 
 struct mv_ddr_topology_map {
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_plat.c b/drivers/ddr/marvell/a38x/mv_ddr_plat.c
index 058e262a61ad..1ab72e36189e 100644
--- a/drivers/ddr/marvell/a38x/mv_ddr_plat.c
+++ b/drivers/ddr/marvell/a38x/mv_ddr_plat.c
@@ -675,11 +675,6 @@ static int mv_ddr_sw_db_init(u32 dev_num, u32 board_id)
 	dfs_low_freq = DFS_LOW_FREQ_VALUE;
 	calibration_update_control = 1;
 
-#ifdef CONFIG_ARMADA_38X
-	/* For a38x only, change to 2T mode to resolve low freq instability */
-	mode_2t = 1;
-#endif
-
 	ddr3_tip_a38x_get_medium_freq(dev_num, &medium_freq);
 
 	return MV_OK;
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_topology.h b/drivers/ddr/marvell/a38x/mv_ddr_topology.h
index 9fd5019ff235..3d801d4f382a 100644
--- a/drivers/ddr/marvell/a38x/mv_ddr_topology.h
+++ b/drivers/ddr/marvell/a38x/mv_ddr_topology.h
@@ -37,6 +37,12 @@ enum mv_ddr_temperature {
 	MV_DDR_TEMP_HIGH
 };
 
+enum mv_ddr_timing {
+	MV_DDR_TIM_DEFAULT,
+	MV_DDR_TIM_1T,
+	MV_DDR_TIM_2T
+};
+
 enum mv_ddr_timing_data {
 	MV_DDR_TCK_AVG_MIN, /* sdram min cycle time (t ck avg min) */
 	MV_DDR_TAA_MIN, /* min cas latency time (t aa min) */
-- 
2.16.2

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH v2 6/6] ARM: mvebu: a38x: use non-zero size for ddr scrubbing
  2018-04-09 10:12 [U-Boot] [PATCH v2 0/6] ARM: mvebu: a38x: updates to ddr training code Chris Packham
                   ` (4 preceding siblings ...)
  2018-04-09 10:12 ` [U-Boot] [PATCH v2 5/6] ARM: mvebu: a38x: restore support for setting timing Chris Packham
@ 2018-04-09 10:12 ` Chris Packham
  2018-05-09 10:23 ` [U-Boot] [PATCH v2 0/6] ARM: mvebu: a38x: updates to ddr training code Stefan Roese
  6 siblings, 0 replies; 8+ messages in thread
From: Chris Packham @ 2018-04-09 10:12 UTC (permalink / raw)
  To: u-boot

From: Chris Packham <chris.packham@alliedtelesis.co.nz>

Make ddr3_calc_mem_cs_size() global scope and use it in
ddr3_new_tip_ecc_scrub to correctly initialize all of DDR memory.

Signed-off-by: Chris Packham <judge.packham@gmail.com>
---
This has been reported upstream at
https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell/pull/6 

Changes in v2: New

 drivers/ddr/marvell/a38x/mv_ddr_plat.c | 2 +-
 drivers/ddr/marvell/a38x/mv_ddr_plat.h | 1 +
 drivers/ddr/marvell/a38x/xor.c         | 3 +++
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/ddr/marvell/a38x/mv_ddr_plat.c b/drivers/ddr/marvell/a38x/mv_ddr_plat.c
index 1ab72e36189e..5a527b67a84d 100644
--- a/drivers/ddr/marvell/a38x/mv_ddr_plat.c
+++ b/drivers/ddr/marvell/a38x/mv_ddr_plat.c
@@ -996,7 +996,7 @@ static u32 ddr3_get_device_size(u32 cs)
 	}
 }
 
-static int ddr3_calc_mem_cs_size(u32 cs, uint64_t *cs_size)
+int ddr3_calc_mem_cs_size(u32 cs, uint64_t *cs_size)
 {
 	u32 cs_mem_size;
 
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_plat.h b/drivers/ddr/marvell/a38x/mv_ddr_plat.h
index 73e54c4b735c..8ea3c8b5c48d 100644
--- a/drivers/ddr/marvell/a38x/mv_ddr_plat.h
+++ b/drivers/ddr/marvell/a38x/mv_ddr_plat.h
@@ -233,4 +233,5 @@ u32 mv_ddr_dm_pad_get(void);
 int mv_ddr_pre_training_fixup(void);
 int mv_ddr_post_training_fixup(void);
 int mv_ddr_manual_cal_do(void);
+int ddr3_calc_mem_cs_size(u32 cs, uint64_t *cs_size);
 #endif /* _MV_DDR_PLAT_H */
diff --git a/drivers/ddr/marvell/a38x/xor.c b/drivers/ddr/marvell/a38x/xor.c
index 368432165fa3..d2f90449d5ed 100644
--- a/drivers/ddr/marvell/a38x/xor.c
+++ b/drivers/ddr/marvell/a38x/xor.c
@@ -348,6 +348,9 @@ void ddr3_new_tip_ecc_scrub(void)
 	for (cs_c = 0; cs_c < max_cs; cs_c++)
 		cs_ena |= 1 << cs_c;
 
+	/* assume that all CS have same size */
+	ddr3_calc_mem_cs_size(0, &cs_mem_size);
+
 	mv_sys_xor_init(max_cs, cs_ena, cs_mem_size, 0);
 	total_mem_size = max_cs * cs_mem_size;
 	mv_xor_mem_init(0, 0, total_mem_size, 0xdeadbeef, 0xdeadbeef);
-- 
2.16.2

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [U-Boot] [PATCH v2 0/6] ARM: mvebu: a38x: updates to ddr training code
  2018-04-09 10:12 [U-Boot] [PATCH v2 0/6] ARM: mvebu: a38x: updates to ddr training code Chris Packham
                   ` (5 preceding siblings ...)
  2018-04-09 10:12 ` [U-Boot] [PATCH v2 6/6] ARM: mvebu: a38x: use non-zero size for ddr scrubbing Chris Packham
@ 2018-05-09 10:23 ` Stefan Roese
  6 siblings, 0 replies; 8+ messages in thread
From: Stefan Roese @ 2018-05-09 10:23 UTC (permalink / raw)
  To: u-boot

Hi Chris,

On 09.04.2018 12:12, Chris Packham wrote:
> This series updates the ddr training code in u-boot with the latest
> publicly available version from Marvell which can be found at
> https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git
> (mv_ddr-armada-17.10 branch).
> 
> I've tried to make the delta as small as possible without breaking
> bisect-ability.
> 
> The first 2 patches have already been sent as
> http://patchwork.ozlabs.org/patch/894866/ and
> http://patchwork.ozlabs.org/patch/894865/
> 
> The bulk of the changes are in patch 4. Naturally this doesn't pass
> checkpatch.pl but I'm erring on the side of being able to diff with the
> upstream source. Also due to it's size this patch may not make it to the
> mailing list so the full series can be retrieved from the mv-ddr branch
> of https://github.com/cpackham/u-boot.git.
> 
> I've tested this series on the db-88f6820-amc board and on a custom
> board that is not upstream (yet). I've also build tested the other a38x
> boards. More testing on actual hardware would be greatly appreciated.
> 
> Changes in v2:
> - remove unused #include

Many thanks for working on this. I tried to apply the patches today
but failed. Most likely the license SPDX tag changes recently
applied are the problem. Could you please rebase again against
latest master and re-send?

Thanks,
Stefan

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2018-05-09 10:23 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-09 10:12 [U-Boot] [PATCH v2 0/6] ARM: mvebu: a38x: updates to ddr training code Chris Packham
2018-04-09 10:12 ` [U-Boot] [PATCH v2 1/6] ARM: mvebu: a38x: move definition of PEX_CFG_DIRECT_ACCESS Chris Packham
2018-04-09 10:12 ` [U-Boot] [PATCH v2 2/6] ARM: mvebu: a38x: move sys_env_device_rev_get Chris Packham
2018-04-09 10:12 ` [U-Boot] [PATCH v2 3/6] ARM: mvebu: a38x: remove some unused code Chris Packham
2018-04-09 10:12 ` [U-Boot] [PATCH v2 4/6] ARM: mvebu: a38x: sync ddr training code with upstream Chris Packham
2018-04-09 10:12 ` [U-Boot] [PATCH v2 5/6] ARM: mvebu: a38x: restore support for setting timing Chris Packham
2018-04-09 10:12 ` [U-Boot] [PATCH v2 6/6] ARM: mvebu: a38x: use non-zero size for ddr scrubbing Chris Packham
2018-05-09 10:23 ` [U-Boot] [PATCH v2 0/6] ARM: mvebu: a38x: updates to ddr training code Stefan Roese

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.