ARM: mvebu: a38x: sync ddr training code with upstream
authorChris Packham <judge.packham@gmail.com>
Thu, 10 May 2018 01:28:29 +0000 (13:28 +1200)
committerStefan Roese <sr@denx.de>
Mon, 14 May 2018 08:01:56 +0000 (10:01 +0200)
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>
Signed-off-by: Stefan Roese <sr@denx.de>
56 files changed:
board/CZ.NIC/turris_omnia/turris_omnia.c
board/Marvell/db-88f6820-amc/db-88f6820-amc.c
board/Marvell/db-88f6820-gp/db-88f6820-gp.c
board/gdsys/a38x/controlcenterdc.c
board/solidrun/clearfog/clearfog.c
drivers/ddr/marvell/a38x/Makefile
drivers/ddr/marvell/a38x/ddr3_a38x.c [deleted file]
drivers/ddr/marvell/a38x/ddr3_a38x.h [deleted file]
drivers/ddr/marvell/a38x/ddr3_a38x_topology.h [deleted file]
drivers/ddr/marvell/a38x/ddr3_a38x_training.c [deleted file]
drivers/ddr/marvell/a38x/ddr3_debug.c
drivers/ddr/marvell/a38x/ddr3_hws_hw_training.c [deleted file]
drivers/ddr/marvell/a38x/ddr3_hws_hw_training.h [deleted file]
drivers/ddr/marvell/a38x/ddr3_hws_hw_training_def.h [deleted file]
drivers/ddr/marvell/a38x/ddr3_hws_sil_training.h [deleted file]
drivers/ddr/marvell/a38x/ddr3_init.c
drivers/ddr/marvell/a38x/ddr3_init.h
drivers/ddr/marvell/a38x/ddr3_logging_def.h
drivers/ddr/marvell/a38x/ddr3_patterns_64bit.h
drivers/ddr/marvell/a38x/ddr3_topology_def.h
drivers/ddr/marvell/a38x/ddr3_training.c
drivers/ddr/marvell/a38x/ddr3_training_bist.c
drivers/ddr/marvell/a38x/ddr3_training_centralization.c
drivers/ddr/marvell/a38x/ddr3_training_db.c
drivers/ddr/marvell/a38x/ddr3_training_hw_algo.c
drivers/ddr/marvell/a38x/ddr3_training_ip.h
drivers/ddr/marvell/a38x/ddr3_training_ip_bist.h
drivers/ddr/marvell/a38x/ddr3_training_ip_db.h
drivers/ddr/marvell/a38x/ddr3_training_ip_def.h
drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c
drivers/ddr/marvell/a38x/ddr3_training_ip_engine.h
drivers/ddr/marvell/a38x/ddr3_training_ip_flow.h
drivers/ddr/marvell/a38x/ddr3_training_ip_prv_if.h
drivers/ddr/marvell/a38x/ddr3_training_ip_static.h [deleted file]
drivers/ddr/marvell/a38x/ddr3_training_leveling.c
drivers/ddr/marvell/a38x/ddr3_training_leveling.h
drivers/ddr/marvell/a38x/ddr3_training_pbs.c
drivers/ddr/marvell/a38x/ddr3_training_static.c [deleted file]
drivers/ddr/marvell/a38x/ddr_ml_wrapper.h [new file with mode: 0644]
drivers/ddr/marvell/a38x/ddr_topology_def.h
drivers/ddr/marvell/a38x/mv_ddr_build_message.c [new file with mode: 0644]
drivers/ddr/marvell/a38x/mv_ddr_common.c [new file with mode: 0644]
drivers/ddr/marvell/a38x/mv_ddr_common.h [new file with mode: 0644]
drivers/ddr/marvell/a38x/mv_ddr_plat.c [new file with mode: 0644]
drivers/ddr/marvell/a38x/mv_ddr_plat.h [new file with mode: 0644]
drivers/ddr/marvell/a38x/mv_ddr_regs.h [new file with mode: 0644]
drivers/ddr/marvell/a38x/mv_ddr_spd.c [new file with mode: 0644]
drivers/ddr/marvell/a38x/mv_ddr_spd.h [new file with mode: 0644]
drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.c [new file with mode: 0644]
drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.h [new file with mode: 0644]
drivers/ddr/marvell/a38x/mv_ddr_topology.c [new file with mode: 0644]
drivers/ddr/marvell/a38x/mv_ddr_topology.h [new file with mode: 0644]
drivers/ddr/marvell/a38x/seq_exec.h [new file with mode: 0644]
drivers/ddr/marvell/a38x/silicon_if.h [deleted file]
drivers/ddr/marvell/a38x/xor.c
drivers/ddr/marvell/a38x/xor.h

index 58d1f5fe3536721120f6c88c23c4e781f9cc0ab4..29f81cdccfd46ac46a81e256a8226de0c778dc28 100644 (file)
@@ -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;
index ba9738c0f7ee24a731f742d8d2c769bd5114346b..e39dc75f92287f63a15424e9d88ce3ca580cace6 100644 (file)
@@ -11,7 +11,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;
@@ -55,7 +55,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},
@@ -64,17 +65,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;
index fc405b939b9ce2326df10f7d94b9253f0def7328..ee12ca68ec2a1f5ed1ec7895d27bd823d3760cdc 100644 (file)
@@ -11,7 +11,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;
@@ -76,7 +76,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},
@@ -85,17 +86,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;
index 5599767dffb019663907623f3cb44c033c897378..f750e47b72283f426e0967b5b25ed9b20f1dffe8 100644 (file)
@@ -12,7 +12,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"
@@ -39,7 +39,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},
@@ -48,14 +49,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[] = {
@@ -121,7 +124,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;
 }
index 61de16d19e0cb1edf710e230cb7ca2f8ac176339..cc11feb85e30273c4ea002058a548a23adb7002f 100644 (file)
@@ -11,7 +11,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;
@@ -69,7 +69,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},
@@ -78,17 +79,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;
index 5e258bfe6a4ceda9affdab926a2eea9aee7d938d..8251d6db660837e36abbcf4b854c226a5a0e703a 100644 (file)
@@ -1,9 +1,8 @@
 # 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
@@ -13,5 +12,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 (file)
index c356d09..0000000
+++ /dev/null
@@ -1,685 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- */
-
-#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 (file)
index 2543575..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- */
-
-#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 (file)
index be8de88..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- */
-
-#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 (file)
index 7a05e58..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- */
-
-#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;
-}
index c14400840e7e0c3393381b9237a5ef0b60793ab1..1eac0bcd2b2dc0a5e66c394c6ed89eb5292500e1 100644 (file)
@@ -3,13 +3,6 @@
  * Copyright (C) Marvell International Ltd. and its affiliates
  */
 
-#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;
@@ -18,7 +11,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;
@@ -28,7 +26,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)
 {
@@ -52,7 +57,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;
@@ -72,24 +77,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
@@ -98,13 +110,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,
@@ -118,11 +131,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,
@@ -131,9 +144,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,
@@ -163,6 +176,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
  */
@@ -184,7 +214,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
  */
@@ -193,11 +223,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";
 
@@ -209,6 +241,7 @@ static char *convert_freq(enum hws_ddr_freq freq)
 
        case DDR_FREQ_1066:
                return "1066";
+
        case DDR_FREQ_311:
                return "311";
 
@@ -229,6 +262,7 @@ static char *convert_freq(enum hws_ddr_freq freq)
 
        case DDR_FREQ_1000:
                return "DDR_FREQ_1000";
+
        default:
                return "Unknown Frequency";
        }
@@ -279,7 +313,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");
@@ -302,7 +336,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)
 {
@@ -324,9 +358,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;
@@ -340,16 +374,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));
@@ -479,6 +519,7 @@ int ddr3_tip_print_log(u32 dev_num, u32 mem_addr)
        return MV_OK;
 }
 
+#if !defined(EXCLUDE_DEBUG_PRINTS)
 /*
  * Print stability log info
  */
@@ -487,17 +528,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++)
@@ -511,7 +552,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)
@@ -538,11 +579,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));
@@ -550,8 +591,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,
@@ -561,16 +602,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) +
@@ -583,36 +624,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,
@@ -639,6 +670,7 @@ int ddr3_tip_print_stability_log(u32 dev_num)
 
        return MV_OK;
 }
+#endif /* EXCLUDE_DEBUG_PRINTS */
 
 /*
  * Register XSB information
@@ -652,30 +684,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;
                }
        }
@@ -686,24 +718,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,
@@ -717,23 +750,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,
@@ -761,13 +849,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,
@@ -815,7 +904,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;
 
@@ -829,21 +918,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;
@@ -892,15 +977,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:
@@ -932,19 +1016,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:
@@ -976,11 +1056,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:
@@ -988,11 +1068,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:
@@ -1020,7 +1100,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:
@@ -1031,10 +1111,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;
@@ -1079,6 +1155,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;
@@ -1147,28 +1224,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)
@@ -1181,7 +1276,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;
        }
 
@@ -1203,69 +1298,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
  */
@@ -1273,21 +1308,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;
@@ -1296,11 +1333,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++) {
@@ -1312,10 +1350,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
@@ -1323,38 +1360,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]));
+                                                       }
+                                               }
                                        }
                                }
                        }
@@ -1362,10 +1404,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 {
@@ -1382,9 +1424,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]);
                                }
@@ -1396,11 +1438,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);
        }
@@ -1409,16 +1449,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->
@@ -1456,8 +1694,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)
  */
@@ -1467,10 +1706,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;
@@ -1500,13 +1739,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)
@@ -1514,4 +1747,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 (file)
index 114d91e..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- */
-
-#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 (file)
index 55bc0d2..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- */
-
-#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 (file)
index a87fc40..0000000
+++ /dev/null
@@ -1,461 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- */
-
-#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 (file)
index 2f8e3fd..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- */
-
-#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 */
index 73d984ba66a8ded53c29c2db0c0971b7a6a0ca83..27dbf4f44b9858f1db68c2c1117e63e44bfd57c2 100644 (file)
  * Copyright (C) Marvell International Ltd. and its affiliates
  */
 
-#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
@@ -246,464 +37,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));
+       if (mv_ddr_early_init2() != MV_OK)
+               return MV_FAIL;
 
-       /* DLB config */
-       ddr3_new_tip_dlb_config();
+       /* Set training algorithm's parameters */
+       status = mv_ddr_training_params_set(0);
+       if (MV_OK != status)
+               return status;
 
-#if defined(ECC_SUPPORT)
-       if (ddr3_if_ecc_enabled())
-               ddr3_new_tip_ecc_scrub();
-#endif
 
-       printf("%s Training Sequence - Ended Successfully\n", ddr_type);
+       mv_ddr_mc_config();
 
-       return MV_OK;
-}
+       is_manual_cal_done = mv_ddr_manual_cal_do();
 
-/*
- * Name:     ddr3_get_cpu_freq
- * Desc:     read S@R and return CPU frequency
- * Args:
- * Notes:
- * Returns:  required value
- */
-u32 ddr3_get_cpu_freq(void)
-{
-       return ddr3_tip_get_init_freq();
-}
+       mv_ddr_mc_init();
 
-/*
- * 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;
-
-       reg = reg_read(reg_addr);
-
-       temp = (reg >> offset1) & mask1;
-       if (mask2)
-               temp |= (reg >> offset2) & mask2;
+       if (!is_manual_cal_done) {
+       }
 
-       return temp;
-}
 
-/*
- * 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@Reset
-        */
-       chip_board_rev = mv_board_id_get();
-#else
-       /* Marvell boards select DDR mode according to Sample@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);
-
-       return MV_OK;
-}
-
-u32 ddr3_get_bus_width(void)
-{
-       u32 bus_width;
+       /* 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;
 
-       bus_width = (reg_read(REG_SDRAM_CONFIG_ADDR) & 0x8000) >>
-               REG_SDRAM_CONFIG_WIDTH_OFFS;
+       /* 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;
 
-       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) {
index 8cb645ffb59b83ab3d8070181d0b7876fbaf14ba..382bd922f213d0afc3e7c4764fb9b1cf264f7b27 100644 (file)
@@ -6,12 +6,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"
 #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)                \
        {                               \
                        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,
@@ -150,28 +48,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;
@@ -181,39 +78,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;
@@ -221,172 +107,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 */
index fe929bb72ac03c718bf7237c2b3e2b0126237a6b..ad9da1cfffb40c82fc52503637a88f1681cc6199 100644 (file)
 #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,
index ee41048c685959cc424a3b7366b190c2dd46021c..1e2260b8710e310ddfa915d620b20d127bfd876c 100644 (file)
@@ -6,6 +6,7 @@
 #ifndef __DDR3_PATTERNS_64_H
 #define __DDR3_PATTERNS_64_H
 
+#define FAB_OPT                21
 /*
  * Patterns Declerations
  */
index eda2b13f9049a4c9068e396c007d69a1221e2b80..1963bae3e62f114585f089f07970d01518d14124 100644 (file)
@@ -6,8 +6,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,
@@ -53,7 +54,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 {
index fee589b746f069e65cb422dd110fc3d1a4d853f7..1f26d506da3a9425343e771957f773d8ce1c19b0 100644 (file)
@@ -3,48 +3,35 @@
  * Copyright (C) Marvell International Ltd. and its affiliates
  */
 
-#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];
@@ -55,7 +42,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;
@@ -70,25 +57,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
@@ -98,7 +101,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
@@ -111,16 +114,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 };
@@ -179,10 +196,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);
 
@@ -192,12 +213,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;
 }
@@ -209,34 +259,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) {
@@ -245,13 +295,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;
        }
 
@@ -261,17 +311,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;
@@ -302,21 +353,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",
@@ -329,14 +377,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;
@@ -345,57 +393,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
@@ -403,12 +440,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));
                        }
 
@@ -416,17 +453,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;
@@ -437,40 +481,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;
@@ -509,9 +532,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);
@@ -521,9 +546,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
@@ -544,7 +568,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,
@@ -556,53 +581,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));
@@ -614,31 +627,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) {
@@ -648,14 +668,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);
@@ -666,67 +685,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].
@@ -746,29 +768,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);
                }
 
@@ -785,7 +816,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);
                }
        }
@@ -793,12 +824,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)
@@ -806,16 +972,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
@@ -835,19 +1008,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);
                        }
                }
        }
@@ -867,12 +1037,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);
 }
 
 /*
@@ -881,14 +1047,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;
 }
 
 /*
@@ -897,14 +1058,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;
 }
 
 /*
@@ -918,7 +1074,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;
@@ -930,7 +1086,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++) {
@@ -966,42 +1122,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);
 }
 
 /*
@@ -1012,88 +1134,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
@@ -1104,7 +1148,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;
@@ -1115,7 +1159,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));
@@ -1137,46 +1181,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 */
@@ -1189,11 +1239,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;
@@ -1203,18 +1253,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,
@@ -1234,7 +1287,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,
@@ -1247,8 +1300,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 =
@@ -1259,6 +1311,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];
@@ -1272,7 +1336,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].
@@ -1281,19 +1345,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 */
@@ -1343,27 +1407,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
@@ -1373,14 +1447,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) {
@@ -1398,25 +1472,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,
@@ -1431,15 +1504,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 */
@@ -1454,16 +1527,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);
                }
 
@@ -1481,10 +1554,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)"));
                }
@@ -1506,54 +1579,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));
                }
        }
@@ -1576,20 +1652,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;
 }
@@ -1602,88 +1678,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
  */
@@ -1712,13 +1846,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;
@@ -1733,10 +1867,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;
@@ -1752,13 +1886,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;
@@ -1768,7 +1903,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,
@@ -1776,7 +1911,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);
                        }
                }
@@ -1788,27 +1923,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"));
@@ -1863,35 +1996,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));
                }
        }
 
@@ -1901,7 +2056,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;
@@ -1914,16 +2069,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);
@@ -1938,39 +2095,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"));
@@ -2001,10 +2191,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]));
@@ -2020,6 +2225,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;
@@ -2038,6 +2258,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;
 
@@ -2064,7 +2292,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);
@@ -2188,6 +2416,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) {
@@ -2202,7 +2436,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) {
@@ -2244,6 +2478,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"));
        }
@@ -2311,6 +2560,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;
@@ -2347,7 +2597,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;
@@ -2357,7 +2608,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) {
@@ -2371,9 +2622,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;
@@ -2389,7 +2642,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;
@@ -2402,18 +2668,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",
@@ -2423,9 +2690,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;
@@ -2435,7 +2702,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));
                }
        }
@@ -2512,7 +2779,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;
@@ -2520,18 +2787,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));
@@ -2585,14 +2852,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) {
                /*
index ae2f44d0d97a1bc750760355bd75e8d0dd7bbab2..e29b1713f9a053120629d321853d262bc79fc3fd 100644 (file)
@@ -3,12 +3,6 @@
  * Copyright (C) Marvell International Ltd. and its affiliates
  */
 
-#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;
@@ -24,7 +18,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,
@@ -32,103 +26,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;
 }
@@ -141,34 +75,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;
@@ -187,10 +121,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,
@@ -233,13 +167,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;
 }
@@ -253,11 +184,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) {
@@ -273,9 +203,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,
@@ -286,3 +214,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;
+}
index 614a478bf6f8c66fc525d04474980b69fb9dd602..03e5c9fdcea3320a0ba29acc7b973e3991b2644c 100644 (file)
@@ -3,12 +3,6 @@
  * Copyright (C) Marvell International Ltd. and its affiliates
  */
 
-#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)           \
@@ -22,6 +16,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];
@@ -65,7 +60,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];
@@ -81,33 +77,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;
@@ -133,11 +129,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;
@@ -336,8 +332,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 */
@@ -345,15 +343,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) {
@@ -440,21 +437,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 */
@@ -480,9 +477,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));
        }
@@ -508,29 +505,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,
@@ -544,10 +542,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;
@@ -620,13 +618,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);
@@ -636,7 +633,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(
@@ -649,25 +646,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",
@@ -694,15 +695,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]);
                }
        }
index 27473acae335359c430359c1c7db17db49dc0689..c0089f67f271f561d8520c55e4fc14aa2a2987b0 100644 (file)
@@ -3,16 +3,25 @@
  * Copyright (C) Marvell International Ltd. and its affiliates
  */
 
-#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, */
@@ -151,18 +160,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[] = {
@@ -209,7 +218,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[] = {
@@ -233,7 +246,7 @@ u32 speed_bin_table_t_rc[] = {
        43285,
        44220,
        45155,
-       46900
+       46090
 };
 
 u32 speed_bin_table_t_rcd_t_rp[] = {
@@ -255,7 +268,7 @@ u32 speed_bin_table_t_rcd_t_rp[] = {
        12840,
        13910,
        10285,
-       11022,
+       11220,
        12155,
        13090,
 };
@@ -356,13 +369,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;
@@ -371,49 +384,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;
@@ -465,14 +478,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);
@@ -488,6 +494,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] >>
@@ -527,13 +606,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:
@@ -577,9 +656,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:
@@ -591,7 +670,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;
                }
@@ -630,7 +736,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;
@@ -644,7 +753,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;
                }
@@ -652,3 +788,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;
+}
index fff1d799ce4fcf89b7c5864fe3e825d4c26a1b22..6b8aae83d759852dadfcfd41df3189d5401f24e2 100644 (file)
@@ -3,12 +3,6 @@
  * Copyright (C) Marvell International Ltd. and its affiliates
  */
 
-#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
@@ -16,9 +10,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];
@@ -48,45 +41,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;
@@ -100,21 +89,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));
 
@@ -123,7 +110,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;
@@ -138,7 +125,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;
@@ -176,7 +163,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));
 
@@ -190,9 +178,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;
@@ -228,7 +216,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++;
@@ -239,13 +227,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] ==
@@ -263,14 +251,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
@@ -281,10 +269,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,
@@ -609,10 +597,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,
@@ -640,7 +628,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.
@@ -653,22 +641,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);
 
index 0102e6919486a35966cd7d2290da132d2fd30c2c..531103c1abd5ac976614d1400f100da734e42ac0 100644 (file)
 #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)
 #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,
@@ -79,6 +82,7 @@ enum auto_tune_stage {
        TX_EMPHASIS,
        LOAD_PATTERN_HIGH,
        PER_BIT_READ_LEVELING_TF,
+       WRITE_LEVELING_LF,
        MAX_STAGE_LIMIT
 };
 
@@ -110,7 +114,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 {
@@ -167,11 +171,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_ */
index 1d7af4dcd3f825b284be56b573e392818561ffb1..38058cba8a1f9f6f074e22338b169bd62e4206e4 100644 (file)
@@ -45,9 +45,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_ */
index 18e4f98ff7fdbb0733570604188438926e7ea46d..e28b7ecee15ca67cba3906eb2e3ad83eb408f51b 100644 (file)
@@ -9,7 +9,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,
@@ -19,15 +22,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_ */
index 2a30f80f7983c3c2dc711e1b3c8b44ee827684ba..2318ceba29200d210f9b5e68ec0e7df37b65ca9e 100644 (file)
@@ -6,8 +6,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
@@ -35,6 +33,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
@@ -99,6 +98,8 @@
 
 #define _1G                            0x40000000
 #define _2G                            0x80000000
+#define _4G                            0x100000000
+#define _8G                            0x200000000
 
 #define ADDR_SIZE_512MB                        0x04000000
 #define ADDR_SIZE_1GB                  0x08000000
@@ -163,10 +164,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 */
index 89318a48d9641bc7613e2acb41bef5849c79219f..334c2906fdbf0d73ab3dabe0a968d15077d1ee18 100644 (file)
@@ -3,12 +3,6 @@
  * Copyright (C) Marvell International Ltd. and its affiliates
  */
 
-#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
@@ -21,6 +15,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,
@@ -43,14 +38,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,
@@ -68,17 +88,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[] = {
        /*
@@ -87,7 +210,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 */
@@ -97,15 +223,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[] = {
@@ -115,7 +255,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 */
@@ -125,15 +268,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;
@@ -165,6 +322,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
@@ -182,18 +343,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));
        }
@@ -213,20 +375,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));
        }
 
@@ -248,7 +410,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) ?
@@ -271,13 +433,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)));
 
@@ -286,7 +448,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) {
@@ -294,12 +456,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) {
                /*
@@ -310,11 +470,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 at 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  */
@@ -325,12 +485,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;
@@ -342,15 +502,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,
@@ -384,89 +541,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;
 }
@@ -480,32 +572,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;
 }
@@ -527,7 +634,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;
 
@@ -597,7 +704,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,
@@ -605,11 +713,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,
@@ -621,7 +729,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));
        }
@@ -639,11 +747,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",
@@ -689,11 +797,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] =
@@ -737,60 +845,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
  */
@@ -798,7 +873,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 */
        /*
@@ -813,73 +888,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
  */
@@ -902,8 +969,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,
@@ -913,12 +981,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(
@@ -968,7 +1036,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,
@@ -982,48 +1050,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;
@@ -1033,181 +1152,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 {
@@ -1215,27 +1490,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]));
                        }
@@ -1257,7 +1526,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);
 
@@ -1279,11 +1549,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
@@ -1322,11 +1592,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;
@@ -1334,20 +1613,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;
+}
index b19bab1ef1c6ae8a88b1d4fd881623fa17578a52..8fbcff50bb268fa10411a3b6e2bcc62ec39e03cc 100644 (file)
@@ -37,8 +37,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,
@@ -75,10 +73,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_ */
index 06e08dc34dcfb5064984fd975701d0c75c1d390c..6a9ef35f6433220bc5626e4a2f0d8a7c1d75368b 100644 (file)
@@ -8,45 +8,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
 /* 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;
@@ -314,10 +157,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);
@@ -331,18 +175,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_ */
index 352bc0ce264a44e3e16e3977b0585c2e438f9163..f614d688c915248fa10b2beb753c9c2590a13742 100644 (file)
@@ -62,7 +62,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);
@@ -83,16 +83,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 (file)
index d5760fc..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- */
-
-#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_ */
index 3a9e81f1b79bcc0389d0c05ad8e8d55e694fb732..6248ffc3fb332668b8299f1a46957bfcf71d692f 100644 (file)
@@ -3,17 +3,9 @@
  * Copyright (C) Marvell International Ltd. and its affiliates
  */
 
-#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,
@@ -27,26 +19,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++;
                }
@@ -55,13 +51,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 */
@@ -71,82 +71,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++)
@@ -154,18 +81,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);
@@ -183,7 +110,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,
@@ -203,17 +130,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 =
@@ -222,13 +149,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
@@ -252,11 +179,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,
@@ -270,72 +197,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 */
@@ -374,26 +275,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) |
@@ -403,9 +304,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);
                        }
                }
        }
@@ -413,11 +313,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
@@ -426,7 +326,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;
        }
@@ -440,8 +340,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:
@@ -456,7 +356,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),
@@ -481,8 +381,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:
@@ -502,7 +402,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,
@@ -535,38 +435,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);
@@ -584,7 +485,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,
@@ -604,15 +505,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 =
@@ -621,13 +522,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
@@ -651,11 +552,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,
@@ -669,63 +570,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) {
@@ -795,11 +670,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) {
@@ -811,7 +686,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])));
@@ -828,18 +703,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
@@ -881,22 +755,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
@@ -905,7 +779,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;
        }
@@ -918,7 +792,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;
 
@@ -931,8 +806,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;
@@ -953,9 +828,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 };
@@ -967,28 +842,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)));
        }
 
        /*
@@ -998,19 +881,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)"));
                }
@@ -1019,24 +902,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
@@ -1044,110 +933,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]));
                                }
                        }
                }
@@ -1159,15 +1029,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
@@ -1186,16 +1062,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
@@ -1214,6 +1090,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,
@@ -1221,9 +1109,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;
@@ -1259,38 +1145,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;
        }
@@ -1306,28 +1202,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",
@@ -1340,14 +1235,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,
@@ -1355,7 +1248,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",
@@ -1368,21 +1261,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",
@@ -1396,13 +1287,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;
@@ -1410,7 +1299,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;
        }
@@ -1422,87 +1311,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]) ==
@@ -1511,19 +1442,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,
@@ -1544,116 +1476,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
  */
@@ -1662,32 +1488,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++) {
@@ -1698,7 +1525,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,
@@ -1706,8 +1533,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));
@@ -1715,7 +1542,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;
 }
@@ -1728,7 +1555,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++) {
@@ -1739,7 +1567,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,
@@ -1747,8 +1575,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));
@@ -1765,7 +1593,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++) {
@@ -1776,7 +1605,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,
@@ -1785,7 +1614,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,
@@ -1801,16 +1630,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));
@@ -1821,10 +1651,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));
@@ -1833,3 +1663,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;
+}
index 4c3c4177732d14e0c6368931ef9c097513f50b15..96d945a33d6eb555542e1a27b83cb543a7c76885 100644 (file)
@@ -11,6 +11,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_ */
index da7a9d143d5ae5aac44dde718ec7783887118380..0511026afbe2b94765923959b7f07cec303c6c4c 100644 (file)
@@ -3,12 +3,6 @@
  * Copyright (C) Marvell International Ltd. and its affiliates
  */
 
-#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
@@ -23,7 +17,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;
@@ -49,34 +43,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,
@@ -87,10 +80,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;
@@ -100,8 +93,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,
@@ -111,7 +104,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,
@@ -176,10 +169,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;
@@ -335,10 +328,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,
@@ -350,10 +343,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 */
@@ -373,10 +366,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++) {
@@ -400,10 +393,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;
@@ -461,10 +454,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];
                }
        }
@@ -478,11 +471,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;
@@ -627,11 +620,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,
@@ -696,7 +689,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
@@ -707,12 +700,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(
@@ -753,9 +746,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,
@@ -771,28 +764,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) {
@@ -842,18 +839,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) ?
@@ -865,24 +862,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 at 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;
@@ -912,14 +914,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);
@@ -936,21 +938,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,
@@ -965,7 +979,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
@@ -974,13 +988,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 (file)
index 1b4bfb2..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- */
-
-#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 (file)
index 0000000..5bf3239
--- /dev/null
@@ -0,0 +1,148 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ */
+
+#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 */
index aa98774e78641422e139a9e4200f554f873871ae..2c589eb3a6558b3cc0233845785071e1e248082a 100644 (file)
@@ -9,38 +9,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 ...) */
@@ -66,11 +41,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;
@@ -88,33 +63,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 (file)
index 0000000..8e60448
--- /dev/null
@@ -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 (file)
index 0000000..7afabbf
--- /dev/null
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ */
+
+#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 (file)
index 0000000..c71ff44
--- /dev/null
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ */
+
+#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 (file)
index 0000000..ce672e9
--- /dev/null
@@ -0,0 +1,1455 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ */
+
+#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 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 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 (file)
index 0000000..61f1030
--- /dev/null
@@ -0,0 +1,235 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ */
+
+#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 (file)
index 0000000..ceda204
--- /dev/null
@@ -0,0 +1,446 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ */
+
+#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 (file)
index 0000000..e9e7f18
--- /dev/null
@@ -0,0 +1,377 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ */
+
+#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 (file)
index 0000000..b4bfef3
--- /dev/null
@@ -0,0 +1,289 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ */
+
+#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 (file)
index 0000000..c9c6899
--- /dev/null
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ */
+
+#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 (file)
index 0000000..dc6977c
--- /dev/null
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ */
+
+#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 (file)
index 0000000..f56ce06
--- /dev/null
@@ -0,0 +1,197 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ */
+
+#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 (file)
index 0000000..eb017a1
--- /dev/null
@@ -0,0 +1,123 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ */
+
+#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 (file)
index 0000000..fe0cb8f
--- /dev/null
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ */
+
+#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 (file)
index 4efd9b8..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- */
-
-#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 */
index e53834f54a94b7bb65c694a006d7fec4545e2712..024cecd777c5a5d06cc2328d0b82b68fb5fc453b 100644 (file)
@@ -3,13 +3,6 @@
  * Copyright (C) Marvell International Ltd. and its affiliates
  */
 
-#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"
 
 #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;
@@ -67,13 +69,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);
                }
        }
 
@@ -87,10 +95,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]);
 
@@ -153,11 +161,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;
@@ -328,28 +339,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;
+}
index 9ca97350401578b94f9939ac8953f7e456c21701..1e0265036934a300efd72553dede20d6d1fb3926 100644 (file)
@@ -8,8 +8,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 */
@@ -87,5 +85,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