[U-Boot] [PATCH v3 0/6] ARM: mvebu: a38x: updates to ddr training code

This series updates the ddr training code in u-boot with the latest publicly available version from Marvell which can be found at https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git (mv_ddr-armada-17.10 branch).
I've tried to make the delta as small as possible without breaking bisect-ability.
The first 2 patches have already been sent as http://patchwork.ozlabs.org/patch/894866/ and http://patchwork.ozlabs.org/patch/894865/
The bulk of the changes are in patch 4. Naturally this doesn't pass checkpatch.pl but I'm erring on the side of being able to diff with the upstream source. Also due to it's size this patch may not make it to the mailing list so the full series can be retrieved from the mv-ddr branch of https://github.com/cpackham/u-boot.git.
I've tested this series on the db-88f6820-amc board and on a custom board that is not upstream (yet). I've also build tested the other a38x boards. More testing on actual hardware would be greatly appreciated.
This version is rebased against master to mop up the SPDX changes.
Changes in v3: - Update to current SPDX style
Changes in v2: - remove unused #include
Chris Packham (6): ARM: mvebu: a38x: move definition of PEX_CFG_DIRECT_ACCESS ARM: mvebu: a38x: move sys_env_device_rev_get ARM: mvebu: a38x: remove some unused code ARM: mvebu: a38x: sync ddr training code with upstream ARM: mvebu: a38x: restore support for setting timing ARM: mvebu: a38x: use non-zero size for ddr scrubbing
arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h | 1 + arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c | 26 +- arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h | 1 - board/CZ.NIC/turris_omnia/turris_omnia.c | 38 +- board/Marvell/db-88f6820-amc/db-88f6820-amc.c | 21 +- board/Marvell/db-88f6820-gp/db-88f6820-gp.c | 21 +- board/gdsys/a38x/controlcenterdc.c | 22 +- board/solidrun/clearfog/clearfog.c | 21 +- drivers/ddr/marvell/a38x/Makefile | 10 +- drivers/ddr/marvell/a38x/ddr3_a38x.c | 736 -------- drivers/ddr/marvell/a38x/ddr3_a38x.h | 92 - .../ddr/marvell/a38x/ddr3_a38x_mc_static.h | 225 --- drivers/ddr/marvell/a38x/ddr3_a38x_topology.h | 21 - drivers/ddr/marvell/a38x/ddr3_a38x_training.c | 39 - drivers/ddr/marvell/a38x/ddr3_debug.c | 742 +++++--- .../ddr/marvell/a38x/ddr3_hws_hw_training.c | 147 -- .../ddr/marvell/a38x/ddr3_hws_hw_training.h | 48 - .../marvell/a38x/ddr3_hws_hw_training_def.h | 463 ----- .../ddr/marvell/a38x/ddr3_hws_sil_training.h | 16 - drivers/ddr/marvell/a38x/ddr3_init.c | 798 ++------- drivers/ddr/marvell/a38x/ddr3_init.h | 300 +--- drivers/ddr/marvell/a38x/ddr3_logging_def.h | 10 +- .../ddr/marvell/a38x/ddr3_patterns_64bit.h | 1 + drivers/ddr/marvell/a38x/ddr3_topology_def.h | 6 +- drivers/ddr/marvell/a38x/ddr3_training.c | 1491 ++++++++++------- drivers/ddr/marvell/a38x/ddr3_training_bist.c | 548 ++++-- .../a38x/ddr3_training_centralization.c | 108 +- drivers/ddr/marvell/a38x/ddr3_training_db.c | 267 ++- .../ddr/marvell/a38x/ddr3_training_hw_algo.c | 98 +- drivers/ddr/marvell/a38x/ddr3_training_ip.h | 19 +- .../ddr/marvell/a38x/ddr3_training_ip_bist.h | 6 +- .../ddr/marvell/a38x/ddr3_training_ip_db.h | 71 +- .../ddr/marvell/a38x/ddr3_training_ip_def.h | 34 +- .../marvell/a38x/ddr3_training_ip_engine.c | 1134 ++++++++----- .../marvell/a38x/ddr3_training_ip_engine.h | 9 +- .../ddr/marvell/a38x/ddr3_training_ip_flow.h | 305 +--- .../marvell/a38x/ddr3_training_ip_prv_if.h | 17 +- .../marvell/a38x/ddr3_training_ip_static.h | 30 - .../ddr/marvell/a38x/ddr3_training_leveling.c | 1347 ++++++++------- .../ddr/marvell/a38x/ddr3_training_leveling.h | 2 +- drivers/ddr/marvell/a38x/ddr3_training_pbs.c | 201 ++- .../ddr/marvell/a38x/ddr3_training_static.c | 538 ------ drivers/ddr/marvell/a38x/ddr_ml_wrapper.h | 148 ++ drivers/ddr/marvell/a38x/ddr_topology_def.h | 82 +- .../ddr/marvell/a38x/mv_ddr_build_message.c | 1 + drivers/ddr/marvell/a38x/mv_ddr_common.c | 47 + drivers/ddr/marvell/a38x/mv_ddr_common.h | 20 + drivers/ddr/marvell/a38x/mv_ddr_plat.c | 1450 ++++++++++++++++ drivers/ddr/marvell/a38x/mv_ddr_plat.h | 236 +++ drivers/ddr/marvell/a38x/mv_ddr_regs.h | 446 +++++ drivers/ddr/marvell/a38x/mv_ddr_spd.c | 377 +++++ drivers/ddr/marvell/a38x/mv_ddr_spd.h | 289 ++++ drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.c | 102 ++ drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.h | 117 ++ drivers/ddr/marvell/a38x/mv_ddr_topology.c | 197 +++ drivers/ddr/marvell/a38x/mv_ddr_topology.h | 129 ++ drivers/ddr/marvell/a38x/seq_exec.h | 64 + drivers/ddr/marvell/a38x/silicon_if.h | 16 - drivers/ddr/marvell/a38x/xor.c | 185 +- drivers/ddr/marvell/a38x/xor.h | 3 +- 60 files changed, 7984 insertions(+), 5955 deletions(-) delete mode 100644 drivers/ddr/marvell/a38x/ddr3_a38x.c delete mode 100644 drivers/ddr/marvell/a38x/ddr3_a38x.h delete mode 100644 drivers/ddr/marvell/a38x/ddr3_a38x_mc_static.h delete mode 100644 drivers/ddr/marvell/a38x/ddr3_a38x_topology.h delete mode 100644 drivers/ddr/marvell/a38x/ddr3_a38x_training.c delete mode 100644 drivers/ddr/marvell/a38x/ddr3_hws_hw_training.c delete mode 100644 drivers/ddr/marvell/a38x/ddr3_hws_hw_training.h delete mode 100644 drivers/ddr/marvell/a38x/ddr3_hws_hw_training_def.h delete mode 100644 drivers/ddr/marvell/a38x/ddr3_hws_sil_training.h delete mode 100644 drivers/ddr/marvell/a38x/ddr3_training_ip_static.h delete mode 100644 drivers/ddr/marvell/a38x/ddr3_training_static.c create mode 100644 drivers/ddr/marvell/a38x/ddr_ml_wrapper.h create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_build_message.c create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_common.c create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_common.h create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_plat.c create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_plat.h create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_regs.h create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_spd.c create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_spd.h create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.c create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.h create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_topology.c create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_topology.h create mode 100644 drivers/ddr/marvell/a38x/seq_exec.h delete mode 100644 drivers/ddr/marvell/a38x/silicon_if.h

PEX_CFG_DIRECT_ACCESS was defined in ddr3_hws_hw_training_def.h despite only being used in the serdes code. Move this definition to ctrl_pex.h where all the other PEX defines are. Also remove the duplicate definition of PEX_DEVICE_AND_VENDOR_ID which is already defined in ctrl_pex.h.
Signed-off-by: Chris Packham judge.packham@gmail.com ---
Changes in v3: None Changes in v2: None
arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h | 1 + drivers/ddr/marvell/a38x/ddr3_hws_hw_training_def.h | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h index 53ed4eab3203..3f30b6bf972e 100644 --- a/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h +++ b/arch/arm/mach-mvebu/serdes/a38x/ctrl_pex.h @@ -46,6 +46,7 @@
/* Controller revision info */ #define PEX_DEVICE_AND_VENDOR_ID 0x000 +#define PEX_CFG_DIRECT_ACCESS(if, reg) (PEX_IF_REGS_BASE(if) + (reg))
/* PCI Express Configuration Address Register */ #define PXCAR_REG_NUM_OFFS 2 diff --git a/drivers/ddr/marvell/a38x/ddr3_hws_hw_training_def.h b/drivers/ddr/marvell/a38x/ddr3_hws_hw_training_def.h index c99437be22aa..a87fc404cb7d 100644 --- a/drivers/ddr/marvell/a38x/ddr3_hws_hw_training_def.h +++ b/drivers/ddr/marvell/a38x/ddr3_hws_hw_training_def.h @@ -421,8 +421,6 @@
/* Power Management Clock Gating Control Register */ #define POWER_MNG_CTRL_REG 0x18220 -#define PEX_DEVICE_AND_VENDOR_ID 0x000 -#define PEX_CFG_DIRECT_ACCESS(if, reg) (PEX_IF_REGS_BASE(if) + (reg)) #define PMC_PEXSTOPCLOCK_OFFS(p) ((p) < 8 ? (5 + (p)) : (18 + (p))) #define PMC_PEXSTOPCLOCK_MASK(p) (1 << PMC_PEXSTOPCLOCK_OFFS(p)) #define PMC_PEXSTOPCLOCK_EN(p) (1 << PMC_PEXSTOPCLOCK_OFFS(p))

Move sys_env_device_rev_get() from the ddr training code to sys_env_lib.c (which currently resides with the serdes code). This brings sys_env_device_rev_get() into line with sys_env_device_id_get() and sys_env_model_get().
Signed-off-by: Chris Packham judge.packham@gmail.com ---
Changes in v3: None Changes in v2: - remove unused #include
arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c | 26 +++++++++++++++++-- arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h | 1 - drivers/ddr/marvell/a38x/ddr3_init.c | 24 ----------------- 3 files changed, 24 insertions(+), 27 deletions(-)
diff --git a/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c b/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c index d26068e1d774..d387893af37d 100644 --- a/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c +++ b/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c @@ -12,8 +12,6 @@ #include "seq_exec.h" #include "sys_env_lib.h"
-#include "../../../drivers/ddr/marvell/a38x/ddr3_a38x.h" - #ifdef CONFIG_ARMADA_38X enum unit_id sys_env_soc_unit_nums[MAX_UNITS_ID][MAX_DEV_ID_NUM] = { /* 6820 6810 6811 6828 */ @@ -234,3 +232,27 @@ u32 sys_env_device_id_get(void)
return g_dev_id; } + +/* + * sys_env_device_rev_get - Get Marvell controller device revision number + * + * DESCRIPTION: + * This function returns 8bit describing the device revision as defined + * Revision ID Register. + * + * INPUT: + * None. + * + * OUTPUT: + * None. + * + * RETURN: + * 8bit desscribing Marvell controller revision number + */ +u8 sys_env_device_rev_get(void) +{ + u32 value; + + value = reg_read(DEV_VERSION_ID_REG); + return (value & (REVISON_ID_MASK)) >> REVISON_ID_OFFS; +} diff --git a/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h b/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h index c5461067fd88..953445b7d7ae 100644 --- a/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h +++ b/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h @@ -7,7 +7,6 @@ #define _SYS_ENV_LIB_H
#include "../../../drivers/ddr/marvell/a38x/ddr3_init.h" -#include "../../../drivers/ddr/marvell/a38x/ddr3_hws_hw_training.h"
/* Serdes definitions */ #define COMMON_PHY_BASE_ADDR 0x18300 diff --git a/drivers/ddr/marvell/a38x/ddr3_init.c b/drivers/ddr/marvell/a38x/ddr3_init.c index 6ee13c10e493..1c5b1f75ca4f 100644 --- a/drivers/ddr/marvell/a38x/ddr3_init.c +++ b/drivers/ddr/marvell/a38x/ddr3_init.c @@ -107,30 +107,6 @@ static int ddr3_hws_tune_training_params(u8 dev_num); /* A39x revisions */ #define MV_88F69XX_Z1_ID 0x2
-/* - * sys_env_device_rev_get - Get Marvell controller device revision number - * - * DESCRIPTION: - * This function returns 8bit describing the device revision as defined - * Revision ID Register. - * - * INPUT: - * None. - * - * OUTPUT: - * None. - * - * RETURN: - * 8bit desscribing Marvell controller revision number - */ -u8 sys_env_device_rev_get(void) -{ - u32 value; - - value = reg_read(DEV_VERSION_ID_REG); - return (value & (REVISON_ID_MASK)) >> REVISON_ID_OFFS; -} - /* * sys_env_dlb_config_ptr_get *

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

This syncs drivers/ddr/marvell/a38x/ with the mv_ddr-armada-17.10 branch of https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git.
The upstream code is incorporated omitting the ddr4 and apn806 and folding the nested a38x directory up one level. After that a semi-automated step is used to drop unused features with unifdef
find drivers/ddr/marvell/a38x/ -name '*.[ch]' | \ xargs unifdef -m -UMV_DDR -UMV_DDR_ATF -UCONFIG_DDR4 \ -UCONFIG_APN806 -UCONFIG_MC_STATIC \ -UCONFIG_MC_STATIC_PRINT -UCONFIG_PHY_STATIC \ -UCONFIG_64BIT
INTER_REGS_BASE is updated to be defined as SOC_REGS_PHY_BASE.
Some now empty files are removed and the ternary license is replaced with a SPDX GPL-2.0+ identifier.
Signed-off-by: Chris Packham judge.packham@gmail.com ---
Changes in v3: - Update to current SPDX style
Changes in v2: None
board/CZ.NIC/turris_omnia/turris_omnia.c | 36 +- board/Marvell/db-88f6820-amc/db-88f6820-amc.c | 20 +- board/Marvell/db-88f6820-gp/db-88f6820-gp.c | 20 +- board/gdsys/a38x/controlcenterdc.c | 21 +- board/solidrun/clearfog/clearfog.c | 20 +- drivers/ddr/marvell/a38x/Makefile | 10 +- drivers/ddr/marvell/a38x/ddr3_a38x.c | 685 -------- drivers/ddr/marvell/a38x/ddr3_a38x.h | 92 -- drivers/ddr/marvell/a38x/ddr3_a38x_topology.h | 21 - drivers/ddr/marvell/a38x/ddr3_a38x_training.c | 39 - drivers/ddr/marvell/a38x/ddr3_debug.c | 733 ++++++--- .../ddr/marvell/a38x/ddr3_hws_hw_training.c | 147 -- .../ddr/marvell/a38x/ddr3_hws_hw_training.h | 48 - .../marvell/a38x/ddr3_hws_hw_training_def.h | 461 ------ .../ddr/marvell/a38x/ddr3_hws_sil_training.h | 16 - drivers/ddr/marvell/a38x/ddr3_init.c | 745 ++------- drivers/ddr/marvell/a38x/ddr3_init.h | 299 +--- drivers/ddr/marvell/a38x/ddr3_logging_def.h | 10 +- .../ddr/marvell/a38x/ddr3_patterns_64bit.h | 1 + drivers/ddr/marvell/a38x/ddr3_topology_def.h | 6 +- drivers/ddr/marvell/a38x/ddr3_training.c | 1450 +++++++++------- drivers/ddr/marvell/a38x/ddr3_training_bist.c | 548 +++++-- .../a38x/ddr3_training_centralization.c | 108 +- drivers/ddr/marvell/a38x/ddr3_training_db.c | 267 ++- .../ddr/marvell/a38x/ddr3_training_hw_algo.c | 98 +- drivers/ddr/marvell/a38x/ddr3_training_ip.h | 19 +- .../ddr/marvell/a38x/ddr3_training_ip_bist.h | 6 +- .../ddr/marvell/a38x/ddr3_training_ip_db.h | 71 +- .../ddr/marvell/a38x/ddr3_training_ip_def.h | 34 +- .../marvell/a38x/ddr3_training_ip_engine.c | 1134 ++++++++----- .../marvell/a38x/ddr3_training_ip_engine.h | 9 +- .../ddr/marvell/a38x/ddr3_training_ip_flow.h | 305 +--- .../marvell/a38x/ddr3_training_ip_prv_if.h | 17 +- .../marvell/a38x/ddr3_training_ip_static.h | 30 - .../ddr/marvell/a38x/ddr3_training_leveling.c | 1347 ++++++++------- .../ddr/marvell/a38x/ddr3_training_leveling.h | 2 +- drivers/ddr/marvell/a38x/ddr3_training_pbs.c | 201 +-- .../ddr/marvell/a38x/ddr3_training_static.c | 100 -- drivers/ddr/marvell/a38x/ddr_ml_wrapper.h | 148 ++ drivers/ddr/marvell/a38x/ddr_topology_def.h | 83 +- .../ddr/marvell/a38x/mv_ddr_build_message.c | 1 + drivers/ddr/marvell/a38x/mv_ddr_common.c | 47 + drivers/ddr/marvell/a38x/mv_ddr_common.h | 20 + drivers/ddr/marvell/a38x/mv_ddr_plat.c | 1455 +++++++++++++++++ drivers/ddr/marvell/a38x/mv_ddr_plat.h | 235 +++ drivers/ddr/marvell/a38x/mv_ddr_regs.h | 446 +++++ drivers/ddr/marvell/a38x/mv_ddr_spd.c | 377 +++++ drivers/ddr/marvell/a38x/mv_ddr_spd.h | 289 ++++ drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.c | 102 ++ drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.h | 117 ++ drivers/ddr/marvell/a38x/mv_ddr_topology.c | 197 +++ drivers/ddr/marvell/a38x/mv_ddr_topology.h | 123 ++ drivers/ddr/marvell/a38x/seq_exec.h | 64 + drivers/ddr/marvell/a38x/silicon_if.h | 16 - drivers/ddr/marvell/a38x/xor.c | 184 ++- drivers/ddr/marvell/a38x/xor.h | 3 +- 56 files changed, 7944 insertions(+), 5139 deletions(-) delete mode 100644 drivers/ddr/marvell/a38x/ddr3_a38x.c delete mode 100644 drivers/ddr/marvell/a38x/ddr3_a38x.h delete mode 100644 drivers/ddr/marvell/a38x/ddr3_a38x_topology.h delete mode 100644 drivers/ddr/marvell/a38x/ddr3_a38x_training.c delete mode 100644 drivers/ddr/marvell/a38x/ddr3_hws_hw_training.c delete mode 100644 drivers/ddr/marvell/a38x/ddr3_hws_hw_training.h delete mode 100644 drivers/ddr/marvell/a38x/ddr3_hws_hw_training_def.h delete mode 100644 drivers/ddr/marvell/a38x/ddr3_hws_sil_training.h delete mode 100644 drivers/ddr/marvell/a38x/ddr3_training_ip_static.h delete mode 100644 drivers/ddr/marvell/a38x/ddr3_training_static.c create mode 100644 drivers/ddr/marvell/a38x/ddr_ml_wrapper.h create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_build_message.c create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_common.c create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_common.h create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_plat.c create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_plat.h create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_regs.h create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_spd.c create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_spd.h create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.c create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.h create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_topology.c create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_topology.h create mode 100644 drivers/ddr/marvell/a38x/seq_exec.h delete mode 100644 drivers/ddr/marvell/a38x/silicon_if.h
diff --git a/board/CZ.NIC/turris_omnia/turris_omnia.c b/board/CZ.NIC/turris_omnia/turris_omnia.c index 58d1f5fe3536..29f81cdccfd4 100644 --- a/board/CZ.NIC/turris_omnia/turris_omnia.c +++ b/board/CZ.NIC/turris_omnia/turris_omnia.c @@ -27,7 +27,7 @@ # include <wdt.h> #endif
-#include "../drivers/ddr/marvell/a38x/ddr3_a38x_topology.h" +#include "../drivers/ddr/marvell/a38x/ddr3_init.h" #include <../serdes/a38x/high_speed_env_spec.h>
DECLARE_GLOBAL_DATA_PTR; @@ -200,7 +200,8 @@ static bool omnia_read_eeprom(struct omnia_eeprom *oep) * be used by the DDR3 init code in the SPL U-Boot version to configure * the DDR3 controller. */ -static struct hws_topology_map board_topology_map_1g = { +static struct mv_ddr_topology_map board_topology_map_1g = { + DEBUG_LEVEL_ERROR, 0x1, /* active interfaces */ /* cs_mask, mirror, dqs_swap, ck_swap X PUPs */ { { { {0x1, 0, 0, 0}, @@ -209,17 +210,19 @@ static struct hws_topology_map board_topology_map_1g = { {0x1, 0, 0, 0}, {0x1, 0, 0, 0} }, SPEED_BIN_DDR_1600K, /* speed_bin */ - BUS_WIDTH_16, /* memory_width */ - MEM_4G, /* mem_size */ + MV_DDR_DEV_WIDTH_16BIT, /* memory_width */ + MV_DDR_DIE_CAP_4GBIT, /* mem_size */ DDR_FREQ_800, /* frequency */ 0, 0, /* cas_wl cas_l */ - HWS_TEMP_NORMAL, /* temperature */ - HWS_TIM_2T} }, /* timing (force 2t) */ - 5, /* Num Of Bus Per Interface*/ - BUS_MASK_32BIT /* Busses mask */ + MV_DDR_TEMP_NORMAL} }, /* temperature */ + BUS_MASK_32BIT, /* Busses mask */ + MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ + { {0} }, /* raw spd data */ + {0} /* timing parameters */ };
-static struct hws_topology_map board_topology_map_2g = { +static struct mv_ddr_topology_map board_topology_map_2g = { + DEBUG_LEVEL_ERROR, 0x1, /* active interfaces */ /* cs_mask, mirror, dqs_swap, ck_swap X PUPs */ { { { {0x1, 0, 0, 0}, @@ -228,17 +231,18 @@ static struct hws_topology_map board_topology_map_2g = { {0x1, 0, 0, 0}, {0x1, 0, 0, 0} }, SPEED_BIN_DDR_1600K, /* speed_bin */ - BUS_WIDTH_16, /* memory_width */ - MEM_8G, /* mem_size */ + MV_DDR_DEV_WIDTH_16BIT, /* memory_width */ + MV_DDR_DIE_CAP_8GBIT, /* mem_size */ DDR_FREQ_800, /* frequency */ 0, 0, /* cas_wl cas_l */ - HWS_TEMP_NORMAL, /* temperature */ - HWS_TIM_2T} }, /* timing (force 2t) */ - 5, /* Num Of Bus Per Interface*/ - BUS_MASK_32BIT /* Busses mask */ + MV_DDR_TEMP_NORMAL} }, /* temperature */ + BUS_MASK_32BIT, /* Busses mask */ + MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ + { {0} }, /* raw spd data */ + {0} /* timing parameters */ };
-struct hws_topology_map *ddr3_get_topology_map(void) +struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) { static int mem = 0; struct omnia_eeprom oep; diff --git a/board/Marvell/db-88f6820-amc/db-88f6820-amc.c b/board/Marvell/db-88f6820-amc/db-88f6820-amc.c index ba9738c0f7ee..e39dc75f9228 100644 --- a/board/Marvell/db-88f6820-amc/db-88f6820-amc.c +++ b/board/Marvell/db-88f6820-amc/db-88f6820-amc.c @@ -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; diff --git a/board/Marvell/db-88f6820-gp/db-88f6820-gp.c b/board/Marvell/db-88f6820-gp/db-88f6820-gp.c index fc405b939b9c..ee12ca68ec2a 100644 --- a/board/Marvell/db-88f6820-gp/db-88f6820-gp.c +++ b/board/Marvell/db-88f6820-gp/db-88f6820-gp.c @@ -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; diff --git a/board/gdsys/a38x/controlcenterdc.c b/board/gdsys/a38x/controlcenterdc.c index 5599767dffb0..f750e47b7228 100644 --- a/board/gdsys/a38x/controlcenterdc.c +++ b/board/gdsys/a38x/controlcenterdc.c @@ -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; } diff --git a/board/solidrun/clearfog/clearfog.c b/board/solidrun/clearfog/clearfog.c index 61de16d19e0c..cc11feb85e30 100644 --- a/board/solidrun/clearfog/clearfog.c +++ b/board/solidrun/clearfog/clearfog.c @@ -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; diff --git a/drivers/ddr/marvell/a38x/Makefile b/drivers/ddr/marvell/a38x/Makefile index 5e258bfe6a4c..8251d6db6608 100644 --- a/drivers/ddr/marvell/a38x/Makefile +++ b/drivers/ddr/marvell/a38x/Makefile @@ -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 index c356d0900870..000000000000 --- a/drivers/ddr/marvell/a38x/ddr3_a38x.c +++ /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 index 2543575895f5..000000000000 --- a/drivers/ddr/marvell/a38x/ddr3_a38x.h +++ /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 index be8de88f4e87..000000000000 --- a/drivers/ddr/marvell/a38x/ddr3_a38x_topology.h +++ /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 index 7a05e5898835..000000000000 --- a/drivers/ddr/marvell/a38x/ddr3_a38x_training.c +++ /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; -} diff --git a/drivers/ddr/marvell/a38x/ddr3_debug.c b/drivers/ddr/marvell/a38x/ddr3_debug.c index c14400840e7e..1eac0bcd2b2d 100644 --- a/drivers/ddr/marvell/a38x/ddr3_debug.c +++ b/drivers/ddr/marvell/a38x/ddr3_debug.c @@ -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, ®_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, ®_data); + WL_PHY_REG(csindex), + ®_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), ®_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, ®_data); + CTX_PHY_REG(csindex), + ®_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, ®_data); + CRX_PHY_REG(csindex), + ®_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, ®_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, ®_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 index 114d91e3034f..000000000000 --- a/drivers/ddr/marvell/a38x/ddr3_hws_hw_training.c +++ /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 index 55bc0d286a96..000000000000 --- a/drivers/ddr/marvell/a38x/ddr3_hws_hw_training.h +++ /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 index a87fc404cb7d..000000000000 --- a/drivers/ddr/marvell/a38x/ddr3_hws_hw_training_def.h +++ /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 index 2f8e3fdd944b..000000000000 --- a/drivers/ddr/marvell/a38x/ddr3_hws_sil_training.h +++ /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 */ diff --git a/drivers/ddr/marvell/a38x/ddr3_init.c b/drivers/ddr/marvell/a38x/ddr3_init.c index 73d984ba66a8..27dbf4f44b98 100644 --- a/drivers/ddr/marvell/a38x/ddr3_init.c +++ b/drivers/ddr/marvell/a38x/ddr3_init.c @@ -3,239 +3,30 @@ * 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, ¶ms); if (MV_OK != status) { diff --git a/drivers/ddr/marvell/a38x/ddr3_init.h b/drivers/ddr/marvell/a38x/ddr3_init.h index 8cb645ffb59b..382bd922f213 100644 --- a/drivers/ddr/marvell/a38x/ddr3_init.h +++ b/drivers/ddr/marvell/a38x/ddr3_init.h @@ -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" @@ -20,119 +20,9 @@ #include "ddr3_training_ip_flow.h" #include "ddr3_training_ip_pbs.h" #include "ddr3_training_ip_prv_if.h" -#include "ddr3_training_ip_static.h" #include "ddr3_training_leveling.h" #include "xor.h"
-/* - * MV_DEBUG_INIT need to be defines, otherwise the output of the - * DDR2 training code is not complete and misleading - */ -#define MV_DEBUG_INIT - -#ifdef MV_DEBUG_INIT -#define DEBUG_INIT_S(s) puts(s) -#define DEBUG_INIT_D(d, l) printf("%x", d) -#define DEBUG_INIT_D_10(d, l) printf("%d", d) -#else -#define DEBUG_INIT_S(s) -#define DEBUG_INIT_D(d, l) -#define DEBUG_INIT_D_10(d, l) -#endif - -#ifdef MV_DEBUG_INIT_FULL -#define DEBUG_INIT_FULL_S(s) puts(s) -#define DEBUG_INIT_FULL_D(d, l) printf("%x", d) -#define DEBUG_INIT_FULL_D_10(d, l) printf("%d", d) -#define DEBUG_WR_REG(reg, val) \ - { DEBUG_INIT_S("Write Reg: 0x"); DEBUG_INIT_D((reg), 8); \ - DEBUG_INIT_S("= "); DEBUG_INIT_D((val), 8); DEBUG_INIT_S("\n"); } -#define DEBUG_RD_REG(reg, val) \ - { DEBUG_INIT_S("Read Reg: 0x"); DEBUG_INIT_D((reg), 8); \ - DEBUG_INIT_S("= "); DEBUG_INIT_D((val), 8); DEBUG_INIT_S("\n"); } -#else -#define DEBUG_INIT_FULL_S(s) -#define DEBUG_INIT_FULL_D(d, l) -#define DEBUG_INIT_FULL_D_10(d, l) -#define DEBUG_WR_REG(reg, val) -#define DEBUG_RD_REG(reg, val) -#endif - -#define DEBUG_INIT_FULL_C(s, d, l) \ - { DEBUG_INIT_FULL_S(s); \ - DEBUG_INIT_FULL_D(d, l); \ - DEBUG_INIT_FULL_S("\n"); } -#define DEBUG_INIT_C(s, d, l) \ - { DEBUG_INIT_S(s); DEBUG_INIT_D(d, l); DEBUG_INIT_S("\n"); } - -/* - * Debug (Enable/Disable modules) and Error report - */ - -#ifdef BASIC_DEBUG -#define MV_DEBUG_WL -#define MV_DEBUG_RL -#define MV_DEBUG_DQS_RESULTS -#endif - -#ifdef FULL_DEBUG -#define MV_DEBUG_WL -#define MV_DEBUG_RL -#define MV_DEBUG_DQS - -#define MV_DEBUG_PBS -#define MV_DEBUG_DFS -#define MV_DEBUG_MAIN_FULL -#define MV_DEBUG_DFS_FULL -#define MV_DEBUG_DQS_FULL -#define MV_DEBUG_RL_FULL -#define MV_DEBUG_WL_FULL -#endif - -#if defined(CONFIG_ARMADA_38X) -#include "ddr3_a38x.h" -#include "ddr3_a38x_topology.h" -#endif - -/* The following is a list of Marvell status */ -#define MV_ERROR (-1) -#define MV_OK (0x00) /* Operation succeeded */ -#define MV_FAIL (0x01) /* Operation failed */ -#define MV_BAD_VALUE (0x02) /* Illegal value (general) */ -#define MV_OUT_OF_RANGE (0x03) /* The value is out of range */ -#define MV_BAD_PARAM (0x04) /* Illegal parameter in function called */ -#define MV_BAD_PTR (0x05) /* Illegal pointer value */ -#define MV_BAD_SIZE (0x06) /* Illegal size */ -#define MV_BAD_STATE (0x07) /* Illegal state of state machine */ -#define MV_SET_ERROR (0x08) /* Set operation failed */ -#define MV_GET_ERROR (0x09) /* Get operation failed */ -#define MV_CREATE_ERROR (0x0a) /* Fail while creating an item */ -#define MV_NOT_FOUND (0x0b) /* Item not found */ -#define MV_NO_MORE (0x0c) /* No more items found */ -#define MV_NO_SUCH (0x0d) /* No such item */ -#define MV_TIMEOUT (0x0e) /* Time Out */ -#define MV_NO_CHANGE (0x0f) /* Parameter(s) is already in this value */ -#define MV_NOT_SUPPORTED (0x10) /* This request is not support */ -#define MV_NOT_IMPLEMENTED (0x11) /* Request supported but not implemented*/ -#define MV_NOT_INITIALIZED (0x12) /* The item is not initialized */ -#define MV_NO_RESOURCE (0x13) /* Resource not available (memory ...) */ -#define MV_FULL (0x14) /* Item is full (Queue or table etc...) */ -#define MV_EMPTY (0x15) /* Item is empty (Queue or table etc...) */ -#define MV_INIT_ERROR (0x16) /* Error occurred while INIT process */ -#define MV_HW_ERROR (0x17) /* Hardware error */ -#define MV_TX_ERROR (0x18) /* Transmit operation not succeeded */ -#define MV_RX_ERROR (0x19) /* Recieve operation not succeeded */ -#define MV_NOT_READY (0x1a) /* The other side is not ready yet */ -#define MV_ALREADY_EXIST (0x1b) /* Tried to create existing item */ -#define MV_OUT_OF_CPU_MEM (0x1c) /* Cpu memory allocation failed. */ -#define MV_NOT_STARTED (0x1d) /* Not started yet */ -#define MV_BUSY (0x1e) /* Item is busy. */ -#define MV_TERMINATE (0x1f) /* Item terminates it's work. */ -#define MV_NOT_ALIGNED (0x20) /* Wrong alignment */ -#define MV_NOT_ALLOWED (0x21) /* Operation NOT allowed */ -#define MV_WRITE_PROTECT (0x22) /* Write protected */ -#define MV_INVALID (int)(-1) - /* For checking function return values */ #define CHECK_STATUS(orig_func) \ { \ @@ -142,6 +32,14 @@ return status; \ }
+#define GET_MAX_VALUE(x, y) \ + ((x) > (y)) ? (x) : (y) + +#define SUB_VERSION 0 + +/* max number of devices supported by driver */ +#define MAX_DEVICE_NUM 1 + enum log_level { MV_LOG_LEVEL_0, MV_LOG_LEVEL_1, @@ -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 */ diff --git a/drivers/ddr/marvell/a38x/ddr3_logging_def.h b/drivers/ddr/marvell/a38x/ddr3_logging_def.h index fe929bb72ac0..ad9da1cfffb4 100644 --- a/drivers/ddr/marvell/a38x/ddr3_logging_def.h +++ b/drivers/ddr/marvell/a38x/ddr3_logging_def.h @@ -73,10 +73,14 @@ #endif #endif
+ /* Logging defines */ -#define DEBUG_LEVEL_TRACE 1 -#define DEBUG_LEVEL_INFO 2 -#define DEBUG_LEVEL_ERROR 3 +enum mv_ddr_debug_level { + DEBUG_LEVEL_TRACE = 1, + DEBUG_LEVEL_INFO = 2, + DEBUG_LEVEL_ERROR = 3, + DEBUG_LEVEL_LAST +};
enum ddr_lib_debug_block { DEBUG_BLOCK_STATIC, diff --git a/drivers/ddr/marvell/a38x/ddr3_patterns_64bit.h b/drivers/ddr/marvell/a38x/ddr3_patterns_64bit.h index ee41048c6859..1e2260b8710e 100644 --- a/drivers/ddr/marvell/a38x/ddr3_patterns_64bit.h +++ b/drivers/ddr/marvell/a38x/ddr3_patterns_64bit.h @@ -6,6 +6,7 @@ #ifndef __DDR3_PATTERNS_64_H #define __DDR3_PATTERNS_64_H
+#define FAB_OPT 21 /* * Patterns Declerations */ diff --git a/drivers/ddr/marvell/a38x/ddr3_topology_def.h b/drivers/ddr/marvell/a38x/ddr3_topology_def.h index eda2b13f9049..1963bae3e62f 100644 --- a/drivers/ddr/marvell/a38x/ddr3_topology_def.h +++ b/drivers/ddr/marvell/a38x/ddr3_topology_def.h @@ -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 { diff --git a/drivers/ddr/marvell/a38x/ddr3_training.c b/drivers/ddr/marvell/a38x/ddr3_training.c index fee589b746f0..1f26d506da3a 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training.c +++ b/drivers/ddr/marvell/a38x/ddr3_training.c @@ -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) { /* diff --git a/drivers/ddr/marvell/a38x/ddr3_training_bist.c b/drivers/ddr/marvell/a38x/ddr3_training_bist.c index ae2f44d0d97a..e29b1713f9a0 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_bist.c +++ b/drivers/ddr/marvell/a38x/ddr3_training_bist.c @@ -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; +} diff --git a/drivers/ddr/marvell/a38x/ddr3_training_centralization.c b/drivers/ddr/marvell/a38x/ddr3_training_centralization.c index 614a478bf6f8..03e5c9fdcea3 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_centralization.c +++ b/drivers/ddr/marvell/a38x/ddr3_training_centralization.c @@ -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 & (~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]); } } diff --git a/drivers/ddr/marvell/a38x/ddr3_training_db.c b/drivers/ddr/marvell/a38x/ddr3_training_db.c index 27473acae335..c0089f67f271 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_db.c +++ b/drivers/ddr/marvell/a38x/ddr3_training_db.c @@ -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; +} diff --git a/drivers/ddr/marvell/a38x/ddr3_training_hw_algo.c b/drivers/ddr/marvell/a38x/ddr3_training_hw_algo.c index fff1d799ce4f..6b8aae83d759 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_hw_algo.c +++ b/drivers/ddr/marvell/a38x/ddr3_training_hw_algo.c @@ -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, ®_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);
diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip.h b/drivers/ddr/marvell/a38x/ddr3_training_ip.h index 0102e6919486..531103c1abd5 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_ip.h +++ b/drivers/ddr/marvell/a38x/ddr3_training_ip.h @@ -10,11 +10,10 @@ #include "ddr_topology_def.h" #include "ddr_training_ip_db.h"
-#define DDR3_TIP_VERSION_STRING "DDR3 Training Sequence - Ver TIP-1.29." - #define MAX_CS_NUM 4 #define MAX_TOTAL_BUS_NUM (MAX_INTERFACE_NUM * MAX_BUS_NUM) -#define MAX_DQ_NUM 40 +#define TIP_ENG_LOCK 0x02000000 +#define TIP_TX_DLL_RANGE_MAX 64
#define GET_MIN(arg1, arg2) ((arg1) < (arg2)) ? (arg1) : (arg2) #define GET_MAX(arg1, arg2) ((arg1) < (arg2)) ? (arg2) : (arg1) @@ -38,11 +37,15 @@ #define READ_LEVELING_TF_MASK_BIT 0x00010000 #define WRITE_LEVELING_SUPP_TF_MASK_BIT 0x00020000 #define DM_PBS_TX_MASK_BIT 0x00040000 +#define RL_DQS_BURST_MASK_BIT 0x00080000 #define CENTRALIZATION_RX_MASK_BIT 0x00100000 #define CENTRALIZATION_TX_MASK_BIT 0x00200000 #define TX_EMPHASIS_MASK_BIT 0x00400000 #define PER_BIT_READ_LEVELING_TF_MASK_BIT 0x00800000 #define VREF_CALIBRATION_MASK_BIT 0x01000000 +#define WRITE_LEVELING_LF_MASK_BIT 0x02000000 + +/* DDR4 Specific Training Mask bits */
enum hws_result { TEST_FAILED = 0, @@ -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_ */ diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip_bist.h b/drivers/ddr/marvell/a38x/ddr3_training_ip_bist.h index 1d7af4dcd3f8..38058cba8a1f 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_ip_bist.h +++ b/drivers/ddr/marvell/a38x/ddr3_training_ip_bist.h @@ -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_ */ diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip_db.h b/drivers/ddr/marvell/a38x/ddr3_training_ip_db.h index 18e4f98ff7fd..e28b7ecee15c 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_ip_db.h +++ b/drivers/ddr/marvell/a38x/ddr3_training_ip_db.h @@ -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_ */ diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip_def.h b/drivers/ddr/marvell/a38x/ddr3_training_ip_def.h index 2a30f80f7983..2318ceba2920 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_ip_def.h +++ b/drivers/ddr/marvell/a38x/ddr3_training_ip_def.h @@ -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 */ diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c b/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c index 89318a48d964..334c2906fdbf 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c +++ b/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c @@ -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, - ®_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; +} diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.h b/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.h index b19bab1ef1c6..8fbcff50bb26 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.h +++ b/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.h @@ -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_ */ diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip_flow.h b/drivers/ddr/marvell/a38x/ddr3_training_ip_flow.h index 06e08dc34dcf..6a9ef35f6433 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_ip_flow.h +++ b/drivers/ddr/marvell/a38x/ddr3_training_ip_flow.h @@ -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 @@ -66,205 +94,20 @@ /* nsec */ #define TREFI_LOW 7800 #define TREFI_HIGH 3900 +#define AUTO_ZQC_TIMING 15384 + +enum mr_number { + MR_CMD0, + MR_CMD1, + MR_CMD2, + MR_CMD3, + MR_LAST +};
-#define TR2R_VALUE_REG 0x180 -#define TR2R_MASK_REG 0x180 -#define TRFC_MASK_REG 0x7f -#define TR2W_MASK_REG 0x600 -#define TW2W_HIGH_VALUE_REG 0x1800 -#define TW2W_HIGH_MASK_REG 0xf800 -#define TRFC_HIGH_VALUE_REG 0x20000 -#define TRFC_HIGH_MASK_REG 0x70000 -#define TR2R_HIGH_VALUE_REG 0x0 -#define TR2R_HIGH_MASK_REG 0x380000 -#define TMOD_VALUE_REG 0x16000000 -#define TMOD_MASK_REG 0x1e000000 -#define T_VALUE_REG 0x40000000 -#define T_MASK_REG 0xc0000000 -#define AUTO_ZQC_TIMING 15384 -#define WRITE_XBAR_PORT1 0xc03f8077 -#define READ_XBAR_PORT1 0xc03f8073 -#define DISABLE_DDR_TUNING_DATA 0x02294285 -#define ENABLE_DDR_TUNING_DATA 0x12294285 - -#define ODPG_TRAINING_STATUS_REG 0x18488 -#define ODPG_TRAINING_TRIGGER_REG 0x1030 -#define ODPG_STATUS_DONE_REG 0x16fc -#define ODPG_ENABLE_REG 0x186d4 -#define ODPG_ENABLE_OFFS 0 -#define ODPG_DISABLE_OFFS 8 - -#define ODPG_TRAINING_CONTROL_REG 0x1034 -#define ODPG_OBJ1_OPCODE_REG 0x103c -#define ODPG_OBJ1_ITER_CNT_REG 0x10b4 -#define CALIB_OBJ_PRFA_REG 0x10c4 -#define ODPG_WRITE_LEVELING_DONE_CNTR_REG 0x10f8 -#define ODPG_WRITE_READ_MODE_ENABLE_REG 0x10fc -#define TRAINING_OPCODE_1_REG 0x10b4 -#define SDRAM_CONFIGURATION_REG 0x1400 -#define DDR_CONTROL_LOW_REG 0x1404 -#define SDRAM_TIMING_LOW_REG 0x1408 -#define SDRAM_TIMING_HIGH_REG 0x140c -#define SDRAM_ACCESS_CONTROL_REG 0x1410 -#define SDRAM_OPEN_PAGE_CONTROL_REG 0x1414 -#define SDRAM_OPERATION_REG 0x1418 -#define DUNIT_CONTROL_HIGH_REG 0x1424 -#define ODT_TIMING_LOW 0x1428 -#define DDR_TIMING_REG 0x142c -#define ODT_TIMING_HI_REG 0x147c -#define SDRAM_INIT_CONTROL_REG 0x1480 -#define SDRAM_ODT_CONTROL_HIGH_REG 0x1498 -#define DUNIT_ODT_CONTROL_REG 0x149c -#define READ_BUFFER_SELECT_REG 0x14a4 -#define DUNIT_MMASK_REG 0x14b0 -#define CALIB_MACHINE_CTRL_REG 0x14cc -#define DRAM_DLL_TIMING_REG 0x14e0 -#define DRAM_ZQ_INIT_TIMIMG_REG 0x14e4 -#define DRAM_ZQ_TIMING_REG 0x14e8 -#define DFS_REG 0x1528 -#define READ_DATA_SAMPLE_DELAY 0x1538 -#define READ_DATA_READY_DELAY 0x153c -#define TRAINING_REG 0x15b0 -#define TRAINING_SW_1_REG 0x15b4 -#define TRAINING_SW_2_REG 0x15b8 -#define TRAINING_PATTERN_BASE_ADDRESS_REG 0x15bc -#define TRAINING_DBG_1_REG 0x15c0 -#define TRAINING_DBG_2_REG 0x15c4 -#define TRAINING_DBG_3_REG 0x15c8 -#define RANK_CTRL_REG 0x15e0 -#define TIMING_REG 0x15e4 -#define DRAM_PHY_CONFIGURATION 0x15ec -#define MR0_REG 0x15d0 -#define MR1_REG 0x15d4 -#define MR2_REG 0x15d8 -#define MR3_REG 0x15dc -#define TIMING_REG 0x15e4 -#define ODPG_CTRL_CONTROL_REG 0x1600 -#define ODPG_DATA_CONTROL_REG 0x1630 -#define ODPG_PATTERN_ADDR_OFFSET_REG 0x1638 -#define ODPG_DATA_BUF_SIZE_REG 0x163c -#define PHY_LOCK_STATUS_REG 0x1674 -#define PHY_REG_FILE_ACCESS 0x16a0 -#define TRAINING_WRITE_LEVELING_REG 0x16ac -#define ODPG_PATTERN_ADDR_REG 0x16b0 -#define ODPG_PATTERN_DATA_HI_REG 0x16b4 -#define ODPG_PATTERN_DATA_LOW_REG 0x16b8 -#define ODPG_BIST_LAST_FAIL_ADDR_REG 0x16bc -#define ODPG_BIST_DATA_ERROR_COUNTER_REG 0x16c0 -#define ODPG_BIST_FAILED_DATA_HI_REG 0x16c4 -#define ODPG_BIST_FAILED_DATA_LOW_REG 0x16c8 -#define ODPG_WRITE_DATA_ERROR_REG 0x16cc -#define CS_ENABLE_REG 0x16d8 -#define WR_LEVELING_DQS_PATTERN_REG 0x16dc - -#define ODPG_BIST_DONE 0x186d4 -#define ODPG_BIST_DONE_BIT_OFFS 0 -#define ODPG_BIST_DONE_BIT_VALUE 0 - -#define RESULT_CONTROL_BYTE_PUP_0_REG 0x1830 -#define RESULT_CONTROL_BYTE_PUP_1_REG 0x1834 -#define RESULT_CONTROL_BYTE_PUP_2_REG 0x1838 -#define RESULT_CONTROL_BYTE_PUP_3_REG 0x183c -#define RESULT_CONTROL_BYTE_PUP_4_REG 0x18b0 - -#define RESULT_CONTROL_PUP_0_BIT_0_REG 0x18b4 -#define RESULT_CONTROL_PUP_0_BIT_1_REG 0x18b8 -#define RESULT_CONTROL_PUP_0_BIT_2_REG 0x18bc -#define RESULT_CONTROL_PUP_0_BIT_3_REG 0x18c0 -#define RESULT_CONTROL_PUP_0_BIT_4_REG 0x18c4 -#define RESULT_CONTROL_PUP_0_BIT_5_REG 0x18c8 -#define RESULT_CONTROL_PUP_0_BIT_6_REG 0x18cc -#define RESULT_CONTROL_PUP_0_BIT_7_REG 0x18f0 -#define RESULT_CONTROL_PUP_1_BIT_0_REG 0x18f4 -#define RESULT_CONTROL_PUP_1_BIT_1_REG 0x18f8 -#define RESULT_CONTROL_PUP_1_BIT_2_REG 0x18fc -#define RESULT_CONTROL_PUP_1_BIT_3_REG 0x1930 -#define RESULT_CONTROL_PUP_1_BIT_4_REG 0x1934 -#define RESULT_CONTROL_PUP_1_BIT_5_REG 0x1938 -#define RESULT_CONTROL_PUP_1_BIT_6_REG 0x193c -#define RESULT_CONTROL_PUP_1_BIT_7_REG 0x19b0 -#define RESULT_CONTROL_PUP_2_BIT_0_REG 0x19b4 -#define RESULT_CONTROL_PUP_2_BIT_1_REG 0x19b8 -#define RESULT_CONTROL_PUP_2_BIT_2_REG 0x19bc -#define RESULT_CONTROL_PUP_2_BIT_3_REG 0x19c0 -#define RESULT_CONTROL_PUP_2_BIT_4_REG 0x19c4 -#define RESULT_CONTROL_PUP_2_BIT_5_REG 0x19c8 -#define RESULT_CONTROL_PUP_2_BIT_6_REG 0x19cc -#define RESULT_CONTROL_PUP_2_BIT_7_REG 0x19f0 -#define RESULT_CONTROL_PUP_3_BIT_0_REG 0x19f4 -#define RESULT_CONTROL_PUP_3_BIT_1_REG 0x19f8 -#define RESULT_CONTROL_PUP_3_BIT_2_REG 0x19fc -#define RESULT_CONTROL_PUP_3_BIT_3_REG 0x1a30 -#define RESULT_CONTROL_PUP_3_BIT_4_REG 0x1a34 -#define RESULT_CONTROL_PUP_3_BIT_5_REG 0x1a38 -#define RESULT_CONTROL_PUP_3_BIT_6_REG 0x1a3c -#define RESULT_CONTROL_PUP_3_BIT_7_REG 0x1ab0 -#define RESULT_CONTROL_PUP_4_BIT_0_REG 0x1ab4 -#define RESULT_CONTROL_PUP_4_BIT_1_REG 0x1ab8 -#define RESULT_CONTROL_PUP_4_BIT_2_REG 0x1abc -#define RESULT_CONTROL_PUP_4_BIT_3_REG 0x1ac0 -#define RESULT_CONTROL_PUP_4_BIT_4_REG 0x1ac4 -#define RESULT_CONTROL_PUP_4_BIT_5_REG 0x1ac8 -#define RESULT_CONTROL_PUP_4_BIT_6_REG 0x1acc -#define RESULT_CONTROL_PUP_4_BIT_7_REG 0x1af0 - -#define WL_PHY_REG 0x0 -#define WRITE_CENTRALIZATION_PHY_REG 0x1 -#define RL_PHY_REG 0x2 -#define READ_CENTRALIZATION_PHY_REG 0x3 -#define PBS_RX_PHY_REG 0x50 -#define PBS_TX_PHY_REG 0x10 -#define PHY_CONTROL_PHY_REG 0x90 -#define BW_PHY_REG 0x92 -#define RATE_PHY_REG 0x94 -#define CMOS_CONFIG_PHY_REG 0xa2 -#define PAD_ZRI_CALIB_PHY_REG 0xa4 -#define PAD_ODT_CALIB_PHY_REG 0xa6 -#define PAD_CONFIG_PHY_REG 0xa8 -#define PAD_PRE_DISABLE_PHY_REG 0xa9 -#define TEST_ADLL_REG 0xbf -#define CSN_IOB_VREF_REG(cs) (0xdb + (cs * 12)) -#define CSN_IO_BASE_VREF_REG(cs) (0xd0 + (cs * 12)) - -#define RESULT_DB_PHY_REG_ADDR 0xc0 -#define RESULT_DB_PHY_REG_RX_OFFSET 5 -#define RESULT_DB_PHY_REG_TX_OFFSET 0 - -/* TBD - for NP5 use only CS 0 */ -#define PHY_WRITE_DELAY(cs) WL_PHY_REG -/*( ( _cs_ == 0 ) ? 0x0 : 0x4 )*/ -/* TBD - for NP5 use only CS 0 */ -#define PHY_READ_DELAY(cs) RL_PHY_REG - -#define DDR0_ADDR_1 0xf8258 -#define DDR0_ADDR_2 0xf8254 -#define DDR1_ADDR_1 0xf8270 -#define DDR1_ADDR_2 0xf8270 -#define DDR2_ADDR_1 0xf825c -#define DDR2_ADDR_2 0xf825c -#define DDR3_ADDR_1 0xf8264 -#define DDR3_ADDR_2 0xf8260 -#define DDR4_ADDR_1 0xf8274 -#define DDR4_ADDR_2 0xf8274 - -#define GENERAL_PURPOSE_RESERVED0_REG 0x182e0 - -#define GET_BLOCK_ID_MAX_FREQ(dev_num, block_id) 800000 -#define CS0_RD_LVL_REF_DLY_OFFS 0 -#define CS0_RD_LVL_REF_DLY_LEN 0 -#define CS0_RD_LVL_PH_SEL_OFFS 0 -#define CS0_RD_LVL_PH_SEL_LEN 0 - -#define CS_REGISTER_ADDR_OFFSET 4 -#define CALIBRATED_OBJECTS_REG_ADDR_OFFSET 0x10 - -#define MAX_POLLING_ITERATIONS 100000 - -#define PHASE_REG_OFFSET 32 -#define NUM_BYTES_IN_BURST 31 -#define NUM_OF_CS 4 -#define CS_REG_VALUE(cs_num) (cs_mask_reg[cs_num]) -#define ADLL_LENGTH 32 +struct mv_ddr_mr_data { + u32 cmd; + u32 reg_addr; +};
struct write_supp_result { enum hws_wl_supp stage; @@ -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_ */ diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip_prv_if.h b/drivers/ddr/marvell/a38x/ddr3_training_ip_prv_if.h index 352bc0ce264a..f614d688c915 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_ip_prv_if.h +++ b/drivers/ddr/marvell/a38x/ddr3_training_ip_prv_if.h @@ -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 index d5760fce0821..000000000000 --- a/drivers/ddr/marvell/a38x/ddr3_training_ip_static.h +++ /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_ */ diff --git a/drivers/ddr/marvell/a38x/ddr3_training_leveling.c b/drivers/ddr/marvell/a38x/ddr3_training_leveling.c index 3a9e81f1b79b..6248ffc3fb33 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_leveling.c +++ b/drivers/ddr/marvell/a38x/ddr3_training_leveling.c @@ -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, - ®_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, + ®_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, + ®_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, ®_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, ®_val_high); + DEBUG_LEVELING(DEBUG_LEVEL_TRACE, + ("%s: cs %d, step %d, subphy %d, state %d, low 0x%04x, high 0x%04x; move to ", + __func__, effective_cs, i, subphy_id, + rl_state[effective_cs][subphy_id][if_id], + reg_val_low, reg_val_high)); + + switch (rl_state[effective_cs][subphy_id][if_id]) { + case RL_AHEAD: + /* improve search resolution getting closer to the window */ + if (reg_val_low == RD_FIFO_DQS_FALL_EDGE_POS_4 && + reg_val_high == RD_FIFO_DQS_RISE_EDGE_POS_4) { + rl_state[effective_cs][subphy_id][if_id] = RL_INSIDE; + rl_values[effective_cs][subphy_id][if_id] = i; + rl_min_values[effective_cs][subphy_id][if_id] = i; + DEBUG_LEVELING(DEBUG_LEVEL_TRACE, + ("new state %d\n", + rl_state[effective_cs][subphy_id][if_id])); + } else if (reg_val_low == RD_FIFO_DQS_FALL_EDGE_POS_3 && + reg_val_high == RD_FIFO_DQS_RISE_EDGE_POS_3) { + step = (step < 2) ? step : 2; + } else if (reg_val_low == RD_FIFO_DQS_FALL_EDGE_POS_2 && + reg_val_high == RD_FIFO_DQS_RISE_EDGE_POS_2) { + step = (step < 16) ? step : 16; + } else if (reg_val_low == RD_FIFO_DQS_FALL_EDGE_POS_1 && + reg_val_high == RD_FIFO_DQS_RISE_EDGE_POS_1) { + step = (step < 32) ? step : 32; + } else if (reg_val_low == RD_FIFO_DQS_FALL_EDGE_POS_0 && + reg_val_high == RD_FIFO_DQS_RISE_EDGE_POS_0) { + step = (step < 64) ? step : 64; + } else { + /* otherwise, step is unchanged */ + } + break; + case RL_INSIDE: + if (reg_val_low == RD_FIFO_DQS_FALL_EDGE_POS_4 && + reg_val_high == RD_FIFO_DQS_RISE_EDGE_POS_4) { + rl_max_values[effective_cs][subphy_id][if_id] = i; + if ((rl_max_values[effective_cs][subphy_id][if_id] - + rl_min_values[effective_cs][subphy_id][if_id]) > + ADLL_TAPS_IN_CYCLE) { + rl_state[effective_cs][subphy_id][if_id] = RL_BEHIND; + rl_values[effective_cs][subphy_id][if_id] = + (i + rl_values[effective_cs][subphy_id][if_id]) / 2; + pass_lock_num++; + DEBUG_LEVELING(DEBUG_LEVEL_TRACE, + ("new lock %d\n", pass_lock_num)); + if (rl_min_val[effective_cs] > + rl_values[effective_cs][subphy_id][if_id]) + rl_min_val[effective_cs] = + rl_values[effective_cs][subphy_id][if_id]; + if (rl_max_val[effective_cs] < + rl_values[effective_cs][subphy_id][if_id]) + rl_max_val[effective_cs] = + rl_values[effective_cs][subphy_id][if_id]; + step = 2; + } + } + if (reg_val_low != RD_FIFO_DQS_FALL_EDGE_POS_4 || + reg_val_high != RD_FIFO_DQS_RISE_EDGE_POS_4) { + if ((i - rl_values[effective_cs][subphy_id][if_id]) < + RL_JITTER_WIDTH_LMT) { + /* inside the jitter; not valid segment */ + rl_state[effective_cs][subphy_id][if_id] = RL_AHEAD; + DEBUG_LEVELING(DEBUG_LEVEL_TRACE, + ("new state %d; jitter on mask\n", + rl_state[effective_cs][subphy_id][if_id])); + } else { /* finished valid segment */ + rl_state[effective_cs][subphy_id][if_id] = RL_BEHIND; + rl_values[effective_cs][subphy_id][if_id] = + (i + rl_values[effective_cs][subphy_id][if_id]) / 2; + DEBUG_LEVELING(DEBUG_LEVEL_TRACE, + ("new state %d, solution %d\n", + rl_state[effective_cs][subphy_id][if_id], + rl_values[effective_cs][subphy_id][if_id])); + pass_lock_num++; + DEBUG_LEVELING(DEBUG_LEVEL_TRACE, + ("new lock %d\n", pass_lock_num)); + if (rl_min_val[effective_cs] > + rl_values[effective_cs][subphy_id][if_id]) + rl_min_val[effective_cs] = + rl_values[effective_cs][subphy_id][if_id]; + if (rl_max_val[effective_cs] < + rl_values[effective_cs][subphy_id][if_id]) + rl_max_val[effective_cs] = + rl_values[effective_cs][subphy_id][if_id]; + step = 2; + } + } + break; + case RL_BEHIND: /* do nothing */ + break; + } + DEBUG_LEVELING(DEBUG_LEVEL_TRACE, ("\n")); + } + DEBUG_LEVELING(DEBUG_LEVEL_TRACE, ("pass_lock_num %d\n", pass_lock_num)); + /* exit condition */ + if (pass_lock_num == MAX_BUS_NUM) + break; + } /* for-loop on i */ + + if (pass_lock_num != MAX_BUS_NUM) { + DEBUG_LEVELING(DEBUG_LEVEL_ERROR, + ("%s: cs %d, pass_lock_num %d, max_bus_num %d, init_pass_lock_num %d\n", + __func__, effective_cs, pass_lock_num, MAX_BUS_NUM, init_pass_lock_num)); + for (subphy_id = 0; subphy_id < MAX_BUS_NUM; subphy_id++) { + VALIDATE_BUS_ACTIVE(tm->bus_act_mask, subphy_id); + DEBUG_LEVELING(DEBUG_LEVEL_ERROR, + ("%s: subphy %d %s\n", + __func__, subphy_id, + (rl_state[effective_cs][subphy_id][if_id] == RL_BEHIND) ? + "locked" : "not locked")); + } + } + } /* for-loop on effective_cs */ + + /* post-processing read leveling results */ + if_id = 0; + for (effective_cs = 0; effective_cs < max_cs; effective_cs++) { + phase_delta = 0; + i = rl_min_val[effective_cs]; + sdr_cycle_incr = i / TAPS_PER_RD_SAMPLE; /* sdr cycle increment */ + rd_sample = cl_val + 2 * sdr_cycle_incr; + rd_ready = rd_sample + RD_FIFO_DLY; + min_phase = (rl_min_val[effective_cs] - (sdr_cycle_incr * TAPS_PER_RD_SAMPLE)) % MAX_RD_SAMPLES; + max_phase = (rl_max_val[effective_cs] - (sdr_cycle_incr * TAPS_PER_RD_SAMPLE)) % MAX_RD_SAMPLES; + final_rd_sample = rd_sample; + final_rd_ready = rd_ready; + + ddr3_tip_if_write(0, ACCESS_TYPE_UNICAST, 0, RD_DATA_SMPL_DLYS_REG, + rd_sample << RD_SMPL_DLY_CS_OFFS(effective_cs), + RD_SMPL_DLY_CS_MASK << RD_SMPL_DLY_CS_OFFS(effective_cs)); + ddr3_tip_if_write(0, ACCESS_TYPE_UNICAST, 0, RD_DATA_RDY_DLYS_REG, + rd_ready << RD_RDY_DLY_CS_OFFS(effective_cs), + RD_RDY_DLY_CS_MASK << RD_RDY_DLY_CS_OFFS(effective_cs)); + DEBUG_LEVELING(DEBUG_LEVEL_INFO, + ("%s: cs %d, min phase %d, max phase %d, read sample %d\n", + __func__, effective_cs, min_phase, max_phase, rd_sample)); + + for (subphy_id = 0; subphy_id < MAX_BUS_NUM; subphy_id++) { + VALIDATE_BUS_ACTIVE(tm->bus_act_mask, subphy_id); + /* reduce sdr cycle per cs; extract rl adll and phase values */ + i = rl_values[effective_cs][subphy_id][if_id] - (sdr_cycle_incr * TAPS_PER_RD_SAMPLE); + rl_adll_val = i % MAX_RD_SAMPLES; + rl_phase_val = i / MAX_RD_SAMPLES; + rl_phase_val -= phase_delta; + DEBUG_LEVELING(DEBUG_LEVEL_INFO, + ("%s: final results: cs %d, subphy %d, read sample %d read ready %d, rl_phase_val %d, rl_adll_val %d\n", + __func__, effective_cs, subphy_id, final_rd_sample, + final_rd_ready, rl_phase_val, rl_adll_val)); + + rl_val = ((rl_adll_val & RL_REF_DLY_MASK) << RL_REF_DLY_OFFS) | + ((rl_phase_val & RL_PH_SEL_MASK) << RL_PH_SEL_OFFS); + ddr3_tip_bus_write(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ACCESS_TYPE_UNICAST, + subphy_id, subphy_type, RL_PHY_REG(effective_cs), rl_val); + } + } /* for-loop on effective cs */ + + for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) { + VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id); + if (odt_config != 0) + CHECK_STATUS(ddr3_tip_write_additional_odt_setting(dev_num, if_id)); + } + + /* reset read fifo assertion */ + ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST, if_id, SDRAM_CFG_REG, + DATA_PUP_RD_RESET_ENA << DATA_PUP_RD_RESET_OFFS, + DATA_PUP_RD_RESET_MASK << DATA_PUP_RD_RESET_OFFS); + + /* reset read fifo deassertion */ + ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST, if_id, SDRAM_CFG_REG, + DATA_PUP_RD_RESET_DIS << DATA_PUP_RD_RESET_OFFS, + DATA_PUP_RD_RESET_MASK << DATA_PUP_RD_RESET_OFFS); + + return MV_OK; +} diff --git a/drivers/ddr/marvell/a38x/ddr3_training_leveling.h b/drivers/ddr/marvell/a38x/ddr3_training_leveling.h index 4c3c4177732d..96d945a33d6e 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_leveling.h +++ b/drivers/ddr/marvell/a38x/ddr3_training_leveling.h @@ -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_ */ diff --git a/drivers/ddr/marvell/a38x/ddr3_training_pbs.c b/drivers/ddr/marvell/a38x/ddr3_training_pbs.c index da7a9d143d5a..0511026afbe2 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_pbs.c +++ b/drivers/ddr/marvell/a38x/ddr3_training_pbs.c @@ -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 index 1b4bfb2e026c..000000000000 --- a/drivers/ddr/marvell/a38x/ddr3_training_static.c +++ /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 index 000000000000..5bf323992117 --- /dev/null +++ b/drivers/ddr/marvell/a38x/ddr_ml_wrapper.h @@ -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 */ diff --git a/drivers/ddr/marvell/a38x/ddr_topology_def.h b/drivers/ddr/marvell/a38x/ddr_topology_def.h index aa98774e7864..2c589eb3a655 100644 --- a/drivers/ddr/marvell/a38x/ddr_topology_def.h +++ b/drivers/ddr/marvell/a38x/ddr_topology_def.h @@ -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 index 000000000000..8e60448318f2 --- /dev/null +++ b/drivers/ddr/marvell/a38x/mv_ddr_build_message.c @@ -0,0 +1 @@ +const char mv_ddr_build_message[] = ""; const char mv_ddr_version_string[] = "mv_ddr: mv_ddr-armada-17.10.4"; diff --git a/drivers/ddr/marvell/a38x/mv_ddr_common.c b/drivers/ddr/marvell/a38x/mv_ddr_common.c new file mode 100644 index 000000000000..7afabbfd8804 --- /dev/null +++ b/drivers/ddr/marvell/a38x/mv_ddr_common.c @@ -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 index 000000000000..c71ff442edd3 --- /dev/null +++ b/drivers/ddr/marvell/a38x/mv_ddr_common.h @@ -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 index 000000000000..ce672e9dd4fa --- /dev/null +++ b/drivers/ddr/marvell/a38x/mv_ddr_plat.c @@ -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, ®_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, ®_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, ®_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, ®_val); + *data = (reg_val >> PRFA_DATA_OFFS) & PRFA_DATA_MASK; + } + + return MV_OK; +} + +static int mv_ddr_sw_db_init(u32 dev_num, u32 board_id) +{ + struct hws_tip_config_func_db config_func; + + /* new read leveling version */ + config_func.mv_ddr_dunit_read = dunit_read; + config_func.mv_ddr_dunit_write = dunit_write; + config_func.tip_dunit_mux_select_func = + ddr3_tip_a38x_select_ddr_controller; + config_func.tip_get_freq_config_info_func = + ddr3_tip_a38x_get_freq_config; + config_func.tip_set_freq_divider_func = ddr3_tip_a38x_set_divider; + config_func.tip_get_device_info_func = ddr3_tip_a38x_get_device_info; + config_func.tip_get_temperature = ddr3_ctrl_get_junc_temp; + config_func.tip_get_clock_ratio = ddr3_tip_clock_mode; + config_func.tip_external_read = ddr3_tip_ext_read; + config_func.tip_external_write = ddr3_tip_ext_write; + config_func.mv_ddr_phy_read = prfa_read; + config_func.mv_ddr_phy_write = prfa_write; + + ddr3_tip_init_config_func(dev_num, &config_func); + + ddr3_tip_register_dq_table(dev_num, dq_bit_map_2_phy_pin); + + /* set device attributes*/ + ddr3_tip_dev_attr_init(dev_num); + ddr3_tip_dev_attr_set(dev_num, MV_ATTR_TIP_REV, MV_TIP_REV_4); + ddr3_tip_dev_attr_set(dev_num, MV_ATTR_PHY_EDGE, MV_DDR_PHY_EDGE_POSITIVE); + ddr3_tip_dev_attr_set(dev_num, MV_ATTR_OCTET_PER_INTERFACE, DDR_INTERFACE_OCTETS_NUM); +#ifdef CONFIG_ARMADA_39X + ddr3_tip_dev_attr_set(dev_num, MV_ATTR_INTERLEAVE_WA, 1); +#else + ddr3_tip_dev_attr_set(dev_num, MV_ATTR_INTERLEAVE_WA, 0); +#endif + + ca_delay = 0; + delay_enable = 1; + dfs_low_freq = DFS_LOW_FREQ_VALUE; + calibration_update_control = 1; + +#ifdef CONFIG_ARMADA_38X + /* For a38x only, change to 2T mode to resolve low freq instability */ + mode_2t = 1; +#endif + + ddr3_tip_a38x_get_medium_freq(dev_num, &medium_freq); + + return MV_OK; +} + +static int mv_ddr_training_mask_set(void) +{ + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + enum hws_ddr_freq ddr_freq = tm->interface_params[0].memory_freq; + + mask_tune_func = (SET_LOW_FREQ_MASK_BIT | + LOAD_PATTERN_MASK_BIT | + SET_MEDIUM_FREQ_MASK_BIT | WRITE_LEVELING_MASK_BIT | + WRITE_LEVELING_SUPP_MASK_BIT | + READ_LEVELING_MASK_BIT | + PBS_RX_MASK_BIT | + PBS_TX_MASK_BIT | + SET_TARGET_FREQ_MASK_BIT | + WRITE_LEVELING_TF_MASK_BIT | + WRITE_LEVELING_SUPP_TF_MASK_BIT | + READ_LEVELING_TF_MASK_BIT | + CENTRALIZATION_RX_MASK_BIT | + CENTRALIZATION_TX_MASK_BIT); + rl_mid_freq_wa = 1; + + if ((ddr_freq == DDR_FREQ_333) || (ddr_freq == DDR_FREQ_400)) { + mask_tune_func = (WRITE_LEVELING_MASK_BIT | + LOAD_PATTERN_2_MASK_BIT | + WRITE_LEVELING_SUPP_MASK_BIT | + READ_LEVELING_MASK_BIT | + PBS_RX_MASK_BIT | + PBS_TX_MASK_BIT | + CENTRALIZATION_RX_MASK_BIT | + CENTRALIZATION_TX_MASK_BIT); + rl_mid_freq_wa = 0; /* WA not needed if 333/400 is TF */ + } + + /* Supplementary not supported for ECC modes */ + if (1 == ddr3_if_ecc_enabled()) { + mask_tune_func &= ~WRITE_LEVELING_SUPP_TF_MASK_BIT; + mask_tune_func &= ~WRITE_LEVELING_SUPP_MASK_BIT; + mask_tune_func &= ~PBS_TX_MASK_BIT; + mask_tune_func &= ~PBS_RX_MASK_BIT; + } + + return MV_OK; +} + +/* function: mv_ddr_set_calib_controller + * this function sets the controller which will control + * the calibration cycle in the end of the training. + * 1 - internal controller + * 2 - external controller + */ +void mv_ddr_set_calib_controller(void) +{ + calibration_update_control = CAL_UPDATE_CTRL_INT; +} + +static int ddr3_tip_a38x_set_divider(u8 dev_num, u32 if_id, + enum hws_ddr_freq frequency) +{ + u32 divider = 0; + u32 sar_val, ref_clk_satr; + u32 async_val; + + if (if_id != 0) { + DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR, + ("A38x does not support interface 0x%x\n", + if_id)); + return MV_BAD_PARAM; + } + + /* get VCO freq index */ + sar_val = (reg_read(REG_DEVICE_SAR1_ADDR) >> + RST2_CPU_DDR_CLOCK_SELECT_IN_OFFSET) & + RST2_CPU_DDR_CLOCK_SELECT_IN_MASK; + + ref_clk_satr = reg_read(DEVICE_SAMPLE_AT_RESET2_REG); + if (((ref_clk_satr >> DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_OFFSET) & 0x1) == + DEVICE_SAMPLE_AT_RESET2_REG_REFCLK_25MHZ) + divider = a38x_vco_freq_per_sar_ref_clk_25_mhz[sar_val] / freq_val[frequency]; + else + divider = a38x_vco_freq_per_sar_ref_clk_40_mhz[sar_val] / freq_val[frequency]; + + if ((async_mode_at_tf == 1) && (freq_val[frequency] > 400)) { + /* Set async mode */ + dunit_write(0x20220, 0x1000, 0x1000); + dunit_write(0xe42f4, 0x200, 0x200); + + /* Wait for async mode setup */ + mdelay(5); + + /* Set KNL values */ + switch (frequency) { +#ifdef CONFIG_DDR3 + case DDR_FREQ_467: + async_val = 0x806f012; + break; + case DDR_FREQ_533: + async_val = 0x807f012; + break; + case DDR_FREQ_600: + async_val = 0x805f00a; + break; +#endif + case DDR_FREQ_667: + async_val = 0x809f012; + break; + case DDR_FREQ_800: + async_val = 0x807f00a; + break; +#ifdef CONFIG_DDR3 + case DDR_FREQ_850: + async_val = 0x80cb012; + break; +#endif + case DDR_FREQ_900: + async_val = 0x80d7012; + break; + case DDR_FREQ_933: + async_val = 0x80df012; + break; + case DDR_FREQ_1000: + async_val = 0x80ef012; + break; + case DDR_FREQ_1066: + async_val = 0x80ff012; + break; + default: + /* set DDR_FREQ_667 as default */ + async_val = 0x809f012; + } + dunit_write(0xe42f0, 0xffffffff, async_val); + } else { + /* Set sync mode */ + dunit_write(0x20220, 0x1000, 0x0); + dunit_write(0xe42f4, 0x200, 0x0); + + /* cpupll_clkdiv_reset_mask */ + dunit_write(0xe4264, 0xff, 0x1f); + + /* cpupll_clkdiv_reload_smooth */ + dunit_write(0xe4260, (0xff << 8), (0x2 << 8)); + + /* cpupll_clkdiv_relax_en */ + dunit_write(0xe4260, (0xff << 24), (0x2 << 24)); + + /* write the divider */ + dunit_write(0xe4268, (0x3f << 8), (divider << 8)); + + /* set cpupll_clkdiv_reload_ratio */ + dunit_write(0xe4264, (1 << 8), (1 << 8)); + + /* undet cpupll_clkdiv_reload_ratio */ + dunit_write(0xe4264, (1 << 8), 0x0); + + /* clear cpupll_clkdiv_reload_force */ + dunit_write(0xe4260, (0xff << 8), 0x0); + + /* clear cpupll_clkdiv_relax_en */ + dunit_write(0xe4260, (0xff << 24), 0x0); + + /* clear cpupll_clkdiv_reset_mask */ + dunit_write(0xe4264, 0xff, 0x0); + } + + /* Dunit training clock + 1:1/2:1 mode */ + dunit_write(0x18488, (1 << 16), ((ddr3_tip_clock_mode(frequency) & 0x1) << 16)); + dunit_write(0x1524, (1 << 15), ((ddr3_tip_clock_mode(frequency) - 1) << 15)); + + return MV_OK; +} + +/* + * external read from memory + */ +int ddr3_tip_ext_read(u32 dev_num, u32 if_id, u32 reg_addr, + u32 num_of_bursts, u32 *data) +{ + u32 burst_num; + + for (burst_num = 0; burst_num < num_of_bursts * 8; burst_num++) + data[burst_num] = readl(reg_addr + 4 * burst_num); + + return MV_OK; +} + +/* + * external write to memory + */ +int ddr3_tip_ext_write(u32 dev_num, u32 if_id, u32 reg_addr, + u32 num_of_bursts, u32 *data) { + u32 burst_num; + + for (burst_num = 0; burst_num < num_of_bursts * 8; burst_num++) + writel(data[burst_num], reg_addr + 4 * burst_num); + + return MV_OK; +} + +int mv_ddr_early_init(void) +{ + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + + /* FIXME: change this configuration per ddr type + * configure a380 and a390 to work with receiver odt timing + * the odt_config is defined: + * '1' in ddr4 + * '0' in ddr3 + * here the parameter is run over in ddr4 and ddr3 to '1' (in ddr4 the default is '1') + * to configure the odt to work with timing restrictions + */ + + mv_ddr_sw_db_init(0, 0); + + if (tm->interface_params[0].memory_freq != DDR_FREQ_SAR) + async_mode_at_tf = 1; + + return MV_OK; +} + +int mv_ddr_early_init2(void) +{ + mv_ddr_training_mask_set(); + + return MV_OK; +} + +int mv_ddr_pre_training_fixup(void) +{ + return 0; +} + +int mv_ddr_post_training_fixup(void) +{ + return 0; +} + +int ddr3_post_run_alg(void) +{ + return MV_OK; +} + +int ddr3_silicon_post_init(void) +{ + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + + /* Set half bus width */ + if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask)) { + CHECK_STATUS(ddr3_tip_if_write + (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE, + SDRAM_CFG_REG, 0x0, 0x8000)); + } + + return MV_OK; +} + +u32 mv_ddr_init_freq_get(void) +{ + enum hws_ddr_freq freq; + + mv_ddr_sar_freq_get(0, &freq); + + return freq; +} + +static u32 ddr3_get_bus_width(void) +{ + u32 bus_width; + + bus_width = (reg_read(SDRAM_CFG_REG) & 0x8000) >> + BUS_IN_USE_OFFS; + + return (bus_width == 0) ? 16 : 32; +} + +static u32 ddr3_get_device_width(u32 cs) +{ + u32 device_width; + + device_width = (reg_read(SDRAM_ADDR_CTRL_REG) & + (CS_STRUCT_MASK << CS_STRUCT_OFFS(cs))) >> + CS_STRUCT_OFFS(cs); + + return (device_width == 0) ? 8 : 16; +} + +static u32 ddr3_get_device_size(u32 cs) +{ + u32 device_size_low, device_size_high, device_size; + u32 data, cs_low_offset, cs_high_offset; + + cs_low_offset = CS_SIZE_OFFS(cs); + cs_high_offset = CS_SIZE_HIGH_OFFS(cs); + + data = reg_read(SDRAM_ADDR_CTRL_REG); + device_size_low = (data >> cs_low_offset) & 0x3; + device_size_high = (data >> cs_high_offset) & 0x1; + + device_size = device_size_low | (device_size_high << 2); + + switch (device_size) { + case 0: + return 2048; + case 2: + return 512; + case 3: + return 1024; + case 4: + return 4096; + case 5: + return 8192; + case 1: + default: + DEBUG_INIT_C("Error: Wrong device size of Cs: ", cs, 1); + /* zeroes mem size in ddr3_calc_mem_cs_size */ + return 0; + } +} + +static int ddr3_calc_mem_cs_size(u32 cs, uint64_t *cs_size) +{ + u32 cs_mem_size; + + /* Calculate in MiB */ + cs_mem_size = ((ddr3_get_bus_width() / ddr3_get_device_width(cs)) * + ddr3_get_device_size(cs)) / 8; + + /* + * Multiple controller bus width, 2x for 64 bit + * (SoC controller may be 32 or 64 bit, + * so bit 15 in 0x1400, that means if whole bus used or only half, + * have a differnt meaning + */ + cs_mem_size *= DDR_CONTROLLER_BUS_WIDTH_MULTIPLIER; + + if ((cs_mem_size < 128) || (cs_mem_size > 4096)) { + DEBUG_INIT_C("Error: Wrong Memory size of Cs: ", cs, 1); + return MV_BAD_VALUE; + } + + *cs_size = cs_mem_size << 20; /* write cs size in bytes */ + + return MV_OK; +} + +static int ddr3_fast_path_dynamic_cs_size_config(u32 cs_ena) +{ + u32 reg, cs; + uint64_t mem_total_size = 0; + uint64_t cs_mem_size = 0; + uint64_t mem_total_size_c, cs_mem_size_c; + +#ifdef DEVICE_MAX_DRAM_ADDRESS_SIZE + u32 physical_mem_size; + u32 max_mem_size = DEVICE_MAX_DRAM_ADDRESS_SIZE; + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); +#endif + + /* Open fast path windows */ + for (cs = 0; cs < MAX_CS_NUM; cs++) { + if (cs_ena & (1 << cs)) { + /* get CS size */ + if (ddr3_calc_mem_cs_size(cs, &cs_mem_size) != MV_OK) + return MV_FAIL; + +#ifdef DEVICE_MAX_DRAM_ADDRESS_SIZE + /* + * if number of address pins doesn't allow to use max + * mem size that is defined in topology + * mem size is defined by DEVICE_MAX_DRAM_ADDRESS_SIZE + */ + physical_mem_size = mem_size + [tm->interface_params[0].memory_size]; + + if (ddr3_get_device_width(cs) == 16) { + /* + * 16bit mem device can be twice more - no need + * in less significant pin + */ + max_mem_size = DEVICE_MAX_DRAM_ADDRESS_SIZE * 2; + } + + if (physical_mem_size > max_mem_size) { + cs_mem_size = max_mem_size * + (ddr3_get_bus_width() / + ddr3_get_device_width(cs)); + printf("Updated Physical Mem size is from 0x%x to %x\n", + physical_mem_size, + DEVICE_MAX_DRAM_ADDRESS_SIZE); + } +#endif + + /* set fast path window control for the cs */ + reg = 0xffffe1; + reg |= (cs << 2); + reg |= (cs_mem_size - 1) & 0xffff0000; + /*Open fast path Window */ + reg_write(REG_FASTPATH_WIN_CTRL_ADDR(cs), reg); + + /* Set fast path window base address for the cs */ + reg = ((cs_mem_size) * cs) & 0xffff0000; + /* Set base address */ + reg_write(REG_FASTPATH_WIN_BASE_ADDR(cs), reg); + + /* + * Since memory size may be bigger than 4G the summ may + * be more than 32 bit word, + * so to estimate the result divide mem_total_size and + * cs_mem_size by 0x10000 (it is equal to >> 16) + */ + mem_total_size_c = (mem_total_size >> 16) & 0xffffffffffff; + cs_mem_size_c = (cs_mem_size >> 16) & 0xffffffffffff; + /* if the sum less than 2 G - calculate the value */ + if (mem_total_size_c + cs_mem_size_c < 0x10000) + mem_total_size += cs_mem_size; + else /* put max possible size */ + mem_total_size = L2_FILTER_FOR_MAX_MEMORY_SIZE; + } + } + + /* Set L2 filtering to Max Memory size */ + reg_write(ADDRESS_FILTERING_END_REGISTER, mem_total_size); + + return MV_OK; +} + +static int ddr3_restore_and_set_final_windows(u32 *win, const char *ddr_type) +{ + u32 win_ctrl_reg, num_of_win_regs; + u32 cs_ena = mv_ddr_sys_env_get_cs_ena_from_reg(); + u32 ui; + + win_ctrl_reg = REG_XBAR_WIN_4_CTRL_ADDR; + num_of_win_regs = 16; + + /* Return XBAR windows 4-7 or 16-19 init configuration */ + for (ui = 0; ui < num_of_win_regs; ui++) + reg_write((win_ctrl_reg + 0x4 * ui), win[ui]); + + printf("%s Training Sequence - Switching XBAR Window to FastPath Window\n", + ddr_type); + +#if defined DYNAMIC_CS_SIZE_CONFIG + if (ddr3_fast_path_dynamic_cs_size_config(cs_ena) != MV_OK) + printf("ddr3_fast_path_dynamic_cs_size_config FAILED\n"); +#else + u32 reg, cs; + reg = 0x1fffffe1; + for (cs = 0; cs < MAX_CS_NUM; cs++) { + if (cs_ena & (1 << cs)) { + reg |= (cs << 2); + break; + } + } + /* Open fast path Window to - 0.5G */ + reg_write(REG_FASTPATH_WIN_CTRL_ADDR(0), reg); +#endif + + return MV_OK; +} + +static int ddr3_save_and_set_training_windows(u32 *win) +{ + u32 cs_ena; + u32 reg, tmp_count, cs, ui; + u32 win_ctrl_reg, win_base_reg, win_remap_reg; + u32 num_of_win_regs, win_jump_index; + win_ctrl_reg = REG_XBAR_WIN_4_CTRL_ADDR; + win_base_reg = REG_XBAR_WIN_4_BASE_ADDR; + win_remap_reg = REG_XBAR_WIN_4_REMAP_ADDR; + win_jump_index = 0x10; + num_of_win_regs = 16; + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + +#ifdef DISABLE_L2_FILTERING_DURING_DDR_TRAINING + /* + * Disable L2 filtering during DDR training + * (when Cross Bar window is open) + */ + reg_write(ADDRESS_FILTERING_END_REGISTER, 0); +#endif + + cs_ena = tm->interface_params[0].as_bus_params[0].cs_bitmask; + + /* Close XBAR Window 19 - Not needed */ + /* {0x000200e8} - Open Mbus Window - 2G */ + reg_write(REG_XBAR_WIN_19_CTRL_ADDR, 0); + + /* Save XBAR Windows 4-19 init configurations */ + for (ui = 0; ui < num_of_win_regs; ui++) + win[ui] = reg_read(win_ctrl_reg + 0x4 * ui); + + /* Open XBAR Windows 4-7 or 16-19 for other CS */ + reg = 0; + tmp_count = 0; + for (cs = 0; cs < MAX_CS_NUM; cs++) { + if (cs_ena & (1 << cs)) { + switch (cs) { + case 0: + reg = 0x0e00; + break; + case 1: + reg = 0x0d00; + break; + case 2: + reg = 0x0b00; + break; + case 3: + reg = 0x0700; + break; + } + reg |= (1 << 0); + reg |= (SDRAM_CS_SIZE & 0xffff0000); + + reg_write(win_ctrl_reg + win_jump_index * tmp_count, + reg); + reg = (((SDRAM_CS_SIZE + 1) * (tmp_count)) & + 0xffff0000); + reg_write(win_base_reg + win_jump_index * tmp_count, + reg); + + if (win_remap_reg <= REG_XBAR_WIN_7_REMAP_ADDR) + reg_write(win_remap_reg + + win_jump_index * tmp_count, 0); + + tmp_count++; + } + } + + return MV_OK; +} + +static u32 win[16]; + +int mv_ddr_pre_training_soc_config(const char *ddr_type) +{ + u32 soc_num; + u32 reg_val; + + /* Switching CPU to MRVL ID */ + soc_num = (reg_read(REG_SAMPLE_RESET_HIGH_ADDR) & SAR1_CPU_CORE_MASK) >> + SAR1_CPU_CORE_OFFSET; + switch (soc_num) { + case 0x3: + reg_bit_set(CPU_CONFIGURATION_REG(3), CPU_MRVL_ID_OFFSET); + reg_bit_set(CPU_CONFIGURATION_REG(2), CPU_MRVL_ID_OFFSET); + /* fallthrough */ + case 0x1: + reg_bit_set(CPU_CONFIGURATION_REG(1), CPU_MRVL_ID_OFFSET); + /* fallthrough */ + case 0x0: + reg_bit_set(CPU_CONFIGURATION_REG(0), CPU_MRVL_ID_OFFSET); + /* fallthrough */ + default: + break; + } + + /* + * Set DRAM Reset Mask in case detected GPIO indication of wakeup from + * suspend i.e the DRAM values will not be overwritten / reset when + * waking from suspend + */ + if (mv_ddr_sys_env_suspend_wakeup_check() == + SUSPEND_WAKEUP_ENABLED_GPIO_DETECTED) { + reg_bit_set(SDRAM_INIT_CTRL_REG, + DRAM_RESET_MASK_MASKED << DRAM_RESET_MASK_OFFS); + } + + /* Check if DRAM is already initialized */ + if (reg_read(REG_BOOTROM_ROUTINE_ADDR) & + (1 << REG_BOOTROM_ROUTINE_DRAM_INIT_OFFS)) { + printf("%s Training Sequence - 2nd boot - Skip\n", ddr_type); + return MV_OK; + } + + /* Fix read ready phases for all SOC in reg 0x15c8 */ + reg_val = reg_read(TRAINING_DBG_3_REG); + + reg_val &= ~(TRN_DBG_RDY_INC_PH_2TO1_MASK << TRN_DBG_RDY_INC_PH_2TO1_OFFS(0)); + reg_val |= (0x4 << TRN_DBG_RDY_INC_PH_2TO1_OFFS(0)); /* phase 0 */ + + reg_val &= ~(TRN_DBG_RDY_INC_PH_2TO1_MASK << TRN_DBG_RDY_INC_PH_2TO1_OFFS(1)); + reg_val |= (0x4 << TRN_DBG_RDY_INC_PH_2TO1_OFFS(1)); /* phase 1 */ + + reg_val &= ~(TRN_DBG_RDY_INC_PH_2TO1_MASK << TRN_DBG_RDY_INC_PH_2TO1_OFFS(3)); + reg_val |= (0x6 << TRN_DBG_RDY_INC_PH_2TO1_OFFS(3)); /* phase 3 */ + + reg_val &= ~(TRN_DBG_RDY_INC_PH_2TO1_MASK << TRN_DBG_RDY_INC_PH_2TO1_OFFS(4)); + reg_val |= (0x6 << TRN_DBG_RDY_INC_PH_2TO1_OFFS(4)); /* phase 4 */ + + reg_val &= ~(TRN_DBG_RDY_INC_PH_2TO1_MASK << TRN_DBG_RDY_INC_PH_2TO1_OFFS(5)); + reg_val |= (0x6 << TRN_DBG_RDY_INC_PH_2TO1_OFFS(5)); /* phase 5 */ + + reg_write(TRAINING_DBG_3_REG, reg_val); + + /* + * Axi_bresp_mode[8] = Compliant, + * Axi_addr_decode_cntrl[11] = Internal, + * Axi_data_bus_width[0] = 128bit + * */ + /* 0x14a8 - AXI Control Register */ + reg_write(AXI_CTRL_REG, 0); + + /* + * Stage 2 - Training Values Setup + */ + /* Set X-BAR windows for the training sequence */ + ddr3_save_and_set_training_windows(win); + + return MV_OK; +} + +static int ddr3_new_tip_dlb_config(void) +{ + u32 reg, i = 0; + struct dlb_config *config_table_ptr = sys_env_dlb_config_ptr_get(); + + /* Write the configuration */ + while (config_table_ptr[i].reg_addr != 0) { + reg_write(config_table_ptr[i].reg_addr, + config_table_ptr[i].reg_data); + i++; + } + + + /* Enable DLB */ + reg = reg_read(DLB_CTRL_REG); + reg &= ~(DLB_EN_MASK << DLB_EN_OFFS) & + ~(WR_COALESCE_EN_MASK << WR_COALESCE_EN_OFFS) & + ~(AXI_PREFETCH_EN_MASK << AXI_PREFETCH_EN_OFFS) & + ~(MBUS_PREFETCH_EN_MASK << MBUS_PREFETCH_EN_OFFS) & + ~(PREFETCH_NXT_LN_SZ_TRIG_MASK << PREFETCH_NXT_LN_SZ_TRIG_OFFS); + + reg |= (DLB_EN_ENA << DLB_EN_OFFS) | + (WR_COALESCE_EN_ENA << WR_COALESCE_EN_OFFS) | + (AXI_PREFETCH_EN_ENA << AXI_PREFETCH_EN_OFFS) | + (MBUS_PREFETCH_EN_ENA << MBUS_PREFETCH_EN_OFFS) | + (PREFETCH_NXT_LN_SZ_TRIG_ENA << PREFETCH_NXT_LN_SZ_TRIG_OFFS); + + reg_write(DLB_CTRL_REG, reg); + + return MV_OK; +} + +int mv_ddr_post_training_soc_config(const char *ddr_type) +{ + u32 reg_val; + + /* Restore and set windows */ + ddr3_restore_and_set_final_windows(win, ddr_type); + + /* Update DRAM init indication in bootROM register */ + reg_val = reg_read(REG_BOOTROM_ROUTINE_ADDR); + reg_write(REG_BOOTROM_ROUTINE_ADDR, + reg_val | (1 << REG_BOOTROM_ROUTINE_DRAM_INIT_OFFS)); + + /* DLB config */ + ddr3_new_tip_dlb_config(); + + return MV_OK; +} + +void mv_ddr_mc_config(void) +{ + /* Memory controller initializations */ + struct init_cntr_param init_param; + int status; + + init_param.do_mrs_phy = 1; + init_param.is_ctrl64_bit = 0; + init_param.init_phy = 1; + init_param.msys_init = 1; + status = hws_ddr3_tip_init_controller(0, &init_param); + if (status != MV_OK) + printf("DDR3 init controller - FAILED 0x%x\n", status); + + status = mv_ddr_mc_init(); + if (status != MV_OK) + printf("DDR3 init_sequence - FAILED 0x%x\n", status); +} +/* function: mv_ddr_mc_init + * this function enables the dunit after init controller configuration + */ +int mv_ddr_mc_init(void) +{ + CHECK_STATUS(ddr3_tip_enable_init_sequence(0)); + + return MV_OK; +} + +/* function: ddr3_tip_configure_phy + * configures phy and electrical parameters + */ +int ddr3_tip_configure_phy(u32 dev_num) +{ + u32 if_id, phy_id; + u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE); + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + + CHECK_STATUS(ddr3_tip_bus_write + (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, + ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, + PAD_ZRI_CAL_PHY_REG, + ((0x7f & g_zpri_data) << 7 | (0x7f & g_znri_data)))); + CHECK_STATUS(ddr3_tip_bus_write + (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, + ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL, + PAD_ZRI_CAL_PHY_REG, + ((0x7f & g_zpri_ctrl) << 7 | (0x7f & g_znri_ctrl)))); + CHECK_STATUS(ddr3_tip_bus_write + (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, + ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, + PAD_ODT_CAL_PHY_REG, + ((0x3f & g_zpodt_data) << 6 | (0x3f & g_znodt_data)))); + CHECK_STATUS(ddr3_tip_bus_write + (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, + ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL, + PAD_ODT_CAL_PHY_REG, + ((0x3f & g_zpodt_ctrl) << 6 | (0x3f & g_znodt_ctrl)))); + + CHECK_STATUS(ddr3_tip_bus_write + (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, + ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, + PAD_PRE_DISABLE_PHY_REG, 0)); + CHECK_STATUS(ddr3_tip_bus_write + (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, + ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, + CMOS_CONFIG_PHY_REG, 0)); + CHECK_STATUS(ddr3_tip_bus_write + (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, + ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL, + CMOS_CONFIG_PHY_REG, 0)); + + for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) { + /* check if the interface is enabled */ + VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id); + + for (phy_id = 0; + phy_id < octets_per_if_num; + phy_id++) { + VALIDATE_BUS_ACTIVE(tm->bus_act_mask, phy_id); + /* Vref & clamp */ + CHECK_STATUS(ddr3_tip_bus_read_modify_write + (dev_num, ACCESS_TYPE_UNICAST, + if_id, phy_id, DDR_PHY_DATA, + PAD_CFG_PHY_REG, + ((clamp_tbl[if_id] << 4) | vref_init_val), + ((0x7 << 4) | 0x7))); + /* clamp not relevant for control */ + CHECK_STATUS(ddr3_tip_bus_read_modify_write + (dev_num, ACCESS_TYPE_UNICAST, + if_id, phy_id, DDR_PHY_CONTROL, + PAD_CFG_PHY_REG, 0x4, 0x7)); + } + } + + if (ddr3_tip_dev_attr_get(dev_num, MV_ATTR_PHY_EDGE) == + MV_DDR_PHY_EDGE_POSITIVE) + CHECK_STATUS(ddr3_tip_bus_write + (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, + ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, + DDR_PHY_DATA, 0x90, 0x6002)); + + + return MV_OK; +} + + +int mv_ddr_manual_cal_do(void) +{ + return 0; +} diff --git a/drivers/ddr/marvell/a38x/mv_ddr_plat.h b/drivers/ddr/marvell/a38x/mv_ddr_plat.h new file mode 100644 index 000000000000..61f10302fcca --- /dev/null +++ b/drivers/ddr/marvell/a38x/mv_ddr_plat.h @@ -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 index 000000000000..ceda204a4985 --- /dev/null +++ b/drivers/ddr/marvell/a38x/mv_ddr_regs.h @@ -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 index 000000000000..e9e7f18098b9 --- /dev/null +++ b/drivers/ddr/marvell/a38x/mv_ddr_spd.c @@ -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 index 000000000000..b4bfef31032d --- /dev/null +++ b/drivers/ddr/marvell/a38x/mv_ddr_spd.h @@ -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 index 000000000000..c9c6899e729e --- /dev/null +++ b/drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.c @@ -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 index 000000000000..dc6977c33455 --- /dev/null +++ b/drivers/ddr/marvell/a38x/mv_ddr_sys_env_lib.h @@ -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 index 000000000000..f56ce0677074 --- /dev/null +++ b/drivers/ddr/marvell/a38x/mv_ddr_topology.c @@ -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 index 000000000000..eb017a149726 --- /dev/null +++ b/drivers/ddr/marvell/a38x/mv_ddr_topology.h @@ -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 index 000000000000..fe0cb8f75df2 --- /dev/null +++ b/drivers/ddr/marvell/a38x/seq_exec.h @@ -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 index 4efd9b8b0127..000000000000 --- a/drivers/ddr/marvell/a38x/silicon_if.h +++ /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 */ diff --git a/drivers/ddr/marvell/a38x/xor.c b/drivers/ddr/marvell/a38x/xor.c index e53834f54a94..024cecd777c5 100644 --- a/drivers/ddr/marvell/a38x/xor.c +++ b/drivers/ddr/marvell/a38x/xor.c @@ -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"
@@ -21,39 +14,48 @@ #endif
static u32 ui_xor_regs_ctrl_backup; -static u32 ui_xor_regs_base_backup[MAX_CS]; -static u32 ui_xor_regs_mask_backup[MAX_CS]; +static u32 ui_xor_regs_base_backup[MAX_CS_NUM + 1]; +static u32 ui_xor_regs_mask_backup[MAX_CS_NUM + 1];
-void mv_sys_xor_init(u32 num_of_cs, u32 cs_ena, u32 cs_size, u32 base_delta) +void mv_sys_xor_init(u32 num_of_cs, u32 cs_ena, uint64_t cs_size, u32 base_delta) { - u32 reg, ui, base, cs_count; + u32 reg, ui, cs_count; + uint64_t base, size_mask;
ui_xor_regs_ctrl_backup = reg_read(XOR_WINDOW_CTRL_REG(0, 0)); - for (ui = 0; ui < MAX_CS; ui++) + for (ui = 0; ui < MAX_CS_NUM + 1; ui++) ui_xor_regs_base_backup[ui] = reg_read(XOR_BASE_ADDR_REG(0, ui)); - for (ui = 0; ui < MAX_CS; ui++) + for (ui = 0; ui < MAX_CS_NUM + 1; ui++) ui_xor_regs_mask_backup[ui] = reg_read(XOR_SIZE_MASK_REG(0, ui));
reg = 0; - for (ui = 0; ui < (num_of_cs); ui++) { - /* Enable Window x for each CS */ - reg |= (0x1 << (ui)); - /* Enable Window x for each CS */ - reg |= (0x3 << ((ui * 2) + 16)); + for (ui = 0, cs_count = 0; + (cs_count < num_of_cs) && (ui < 8); + ui++, cs_count++) { + if (cs_ena & (1 << ui)) { + /* Enable Window x for each CS */ + reg |= (0x1 << (ui)); + /* Enable Window x for each CS */ + reg |= (0x3 << ((ui * 2) + 16)); + } }
reg_write(XOR_WINDOW_CTRL_REG(0, 0), reg);
cs_count = 0; - for (ui = 0; ui < num_of_cs; ui++) { + for (ui = 0, cs_count = 0; + (cs_count < num_of_cs) && (ui < 8); + ui++, cs_count++) { if (cs_ena & (1 << ui)) { /* * window x - Base - 0x00000000, * Attribute 0x0e - DRAM */ base = cs_size * ui + base_delta; + /* fixed size 2GB for each CS */ + size_mask = 0x7FFF0000; switch (ui) { case 0: base |= 0xe00; @@ -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; +} diff --git a/drivers/ddr/marvell/a38x/xor.h b/drivers/ddr/marvell/a38x/xor.h index 9ca973504015..1e0265036934 100644 --- a/drivers/ddr/marvell/a38x/xor.h +++ b/drivers/ddr/marvell/a38x/xor.h @@ -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

This restores support for configuring the timing mode based on the ddr_topology. This was originally implemented in commit 90bcc3d38d2b ("driver/ddr: Add support for setting timing in hws_topology_map") but was removed as part of the upstream sync.
Signed-off-by: Chris Packham judge.packham@gmail.com ---
Changes in v3: None Changes in v2: None
board/CZ.NIC/turris_omnia/turris_omnia.c | 6 ++++-- board/Marvell/db-88f6820-amc/db-88f6820-amc.c | 3 ++- board/Marvell/db-88f6820-gp/db-88f6820-gp.c | 3 ++- board/gdsys/a38x/controlcenterdc.c | 3 ++- board/solidrun/clearfog/clearfog.c | 3 ++- drivers/ddr/marvell/a38x/ddr3_training.c | 8 ++++++++ drivers/ddr/marvell/a38x/ddr_topology_def.h | 3 +++ drivers/ddr/marvell/a38x/mv_ddr_plat.c | 5 ----- drivers/ddr/marvell/a38x/mv_ddr_topology.h | 6 ++++++ 9 files changed, 29 insertions(+), 11 deletions(-)
diff --git a/board/CZ.NIC/turris_omnia/turris_omnia.c b/board/CZ.NIC/turris_omnia/turris_omnia.c index 29f81cdccfd4..da663cf1bb0c 100644 --- a/board/CZ.NIC/turris_omnia/turris_omnia.c +++ b/board/CZ.NIC/turris_omnia/turris_omnia.c @@ -214,7 +214,8 @@ static struct mv_ddr_topology_map board_topology_map_1g = { MV_DDR_DIE_CAP_4GBIT, /* mem_size */ DDR_FREQ_800, /* frequency */ 0, 0, /* cas_wl cas_l */ - MV_DDR_TEMP_NORMAL} }, /* temperature */ + MV_DDR_TEMP_NORMAL, /* temperature */ + MV_DDR_TIM_2T} }, /* timing */ BUS_MASK_32BIT, /* Busses mask */ MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ { {0} }, /* raw spd data */ @@ -235,7 +236,8 @@ static struct mv_ddr_topology_map board_topology_map_2g = { MV_DDR_DIE_CAP_8GBIT, /* mem_size */ DDR_FREQ_800, /* frequency */ 0, 0, /* cas_wl cas_l */ - MV_DDR_TEMP_NORMAL} }, /* temperature */ + MV_DDR_TEMP_NORMAL, /* temperature */ + MV_DDR_TIM_2T} }, /* timing */ BUS_MASK_32BIT, /* Busses mask */ MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ { {0} }, /* raw spd data */ diff --git a/board/Marvell/db-88f6820-amc/db-88f6820-amc.c b/board/Marvell/db-88f6820-amc/db-88f6820-amc.c index e39dc75f9228..92d7ae77f07e 100644 --- a/board/Marvell/db-88f6820-amc/db-88f6820-amc.c +++ b/board/Marvell/db-88f6820-amc/db-88f6820-amc.c @@ -69,7 +69,8 @@ static struct mv_ddr_topology_map board_topology_map = { MV_DDR_DIE_CAP_2GBIT, /* mem_size */ DDR_FREQ_800, /* frequency */ 0, 0, /* cas_wl cas_l */ - MV_DDR_TEMP_LOW} }, /* temperature */ + MV_DDR_TEMP_LOW, /* temperature */ + MV_DDR_TIM_DEFAULT} }, /* timing */ BUS_MASK_32BIT, /* Busses mask */ MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ { {0} }, /* raw spd data */ diff --git a/board/Marvell/db-88f6820-gp/db-88f6820-gp.c b/board/Marvell/db-88f6820-gp/db-88f6820-gp.c index ee12ca68ec2a..a8cfe8af0a88 100644 --- a/board/Marvell/db-88f6820-gp/db-88f6820-gp.c +++ b/board/Marvell/db-88f6820-gp/db-88f6820-gp.c @@ -90,7 +90,8 @@ static struct mv_ddr_topology_map board_topology_map = { MV_DDR_DIE_CAP_4GBIT, /* mem_size */ DDR_FREQ_800, /* frequency */ 0, 0, /* cas_wl cas_l */ - MV_DDR_TEMP_LOW} }, /* temperature */ + MV_DDR_TEMP_LOW, /* temperature */ + MV_DDR_TIM_DEFAULT} }, /* timing */ BUS_MASK_32BIT, /* Busses mask */ MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ { {0} }, /* raw spd data */ diff --git a/board/gdsys/a38x/controlcenterdc.c b/board/gdsys/a38x/controlcenterdc.c index f750e47b7228..320bc100c9da 100644 --- a/board/gdsys/a38x/controlcenterdc.c +++ b/board/gdsys/a38x/controlcenterdc.c @@ -53,7 +53,8 @@ static struct mv_ddr_topology_map ddr_topology_map = { MV_DDR_DIE_CAP_4GBIT, /* mem_size */ DDR_FREQ_533, /* frequency */ 0, 0, /* cas_wl cas_l */ - MV_DDR_TEMP_LOW} }, /* temperature */ + MV_DDR_TEMP_LOW, /* temperature */ + MV_DDR_TIM_DEFAULT} }, /* timing */ BUS_MASK_32BIT, /* Busses mask */ MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ { {0} }, /* raw spd data */ diff --git a/board/solidrun/clearfog/clearfog.c b/board/solidrun/clearfog/clearfog.c index cc11feb85e30..ede303d4ebf9 100644 --- a/board/solidrun/clearfog/clearfog.c +++ b/board/solidrun/clearfog/clearfog.c @@ -83,7 +83,8 @@ static struct mv_ddr_topology_map board_topology_map = { MV_DDR_DIE_CAP_4GBIT, /* mem_size */ DDR_FREQ_800, /* frequency */ 0, 0, /* cas_wl cas_l */ - MV_DDR_TEMP_LOW} }, /* temperature */ + MV_DDR_TEMP_LOW, /* temperature */ + MV_DDR_TIM_DEFAULT} }, /* timing */ BUS_MASK_32BIT, /* Busses mask */ MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ { {0} }, /* raw spd data */ diff --git a/drivers/ddr/marvell/a38x/ddr3_training.c b/drivers/ddr/marvell/a38x/ddr3_training.c index 1f26d506da3a..799c5ba089a0 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training.c +++ b/drivers/ddr/marvell/a38x/ddr3_training.c @@ -365,6 +365,7 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_ u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE); struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); enum hws_ddr_freq freq = tm->interface_params[0].memory_freq; + enum mv_ddr_timing timing;
DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE, ("Init_controller, do_mrs_phy=%d, is_ctrl64_bit=%d\n", @@ -603,8 +604,12 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_ DUNIT_CTRL_HIGH_REG, (init_cntr_prm->msys_init << 7), (1 << 7)));
+ timing = tm->interface_params[if_id].timing; + if (mode_2t != 0xff) { t2t = mode_2t; + } else if (timing != MV_DDR_TIM_DEFAULT) { + t2t = (timing == MV_DDR_TIM_2T) ? 1 : 0; } else { /* calculate number of CS (per interface) */ CHECK_STATUS(calc_cs_num @@ -1268,6 +1273,7 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type, u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE); struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); unsigned int tclk; + enum mv_ddr_timing timing = tm->interface_params[if_id].timing;
DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE, ("dev %d access %d IF %d freq %d\n", dev_num, @@ -1410,6 +1416,8 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type, /* Calculate 2T mode */ if (mode_2t != 0xff) { t2t = mode_2t; + } else if (timing != MV_DDR_TIM_DEFAULT) { + t2t = (timing == MV_DDR_TIM_2T) ? 1 : 0; } else { /* Calculate number of CS per interface */ CHECK_STATUS(calc_cs_num(dev_num, if_id, &cs_num)); diff --git a/drivers/ddr/marvell/a38x/ddr_topology_def.h b/drivers/ddr/marvell/a38x/ddr_topology_def.h index 2c589eb3a655..812224909ae4 100644 --- a/drivers/ddr/marvell/a38x/ddr_topology_def.h +++ b/drivers/ddr/marvell/a38x/ddr_topology_def.h @@ -64,6 +64,9 @@ struct if_params {
/* operation temperature */ enum mv_ddr_temperature interface_temp; + + /* 2T vs 1T mode (by default computed from number of CSs) */ + enum mv_ddr_timing timing; };
struct mv_ddr_topology_map { diff --git a/drivers/ddr/marvell/a38x/mv_ddr_plat.c b/drivers/ddr/marvell/a38x/mv_ddr_plat.c index ce672e9dd4fa..2070bb38b099 100644 --- a/drivers/ddr/marvell/a38x/mv_ddr_plat.c +++ b/drivers/ddr/marvell/a38x/mv_ddr_plat.c @@ -674,11 +674,6 @@ static int mv_ddr_sw_db_init(u32 dev_num, u32 board_id) dfs_low_freq = DFS_LOW_FREQ_VALUE; calibration_update_control = 1;
-#ifdef CONFIG_ARMADA_38X - /* For a38x only, change to 2T mode to resolve low freq instability */ - mode_2t = 1; -#endif - ddr3_tip_a38x_get_medium_freq(dev_num, &medium_freq);
return MV_OK; diff --git a/drivers/ddr/marvell/a38x/mv_ddr_topology.h b/drivers/ddr/marvell/a38x/mv_ddr_topology.h index eb017a149726..7bef2d1e0e87 100644 --- a/drivers/ddr/marvell/a38x/mv_ddr_topology.h +++ b/drivers/ddr/marvell/a38x/mv_ddr_topology.h @@ -36,6 +36,12 @@ enum mv_ddr_temperature { MV_DDR_TEMP_HIGH };
+enum mv_ddr_timing { + MV_DDR_TIM_DEFAULT, + MV_DDR_TIM_1T, + MV_DDR_TIM_2T +}; + enum mv_ddr_timing_data { MV_DDR_TCK_AVG_MIN, /* sdram min cycle time (t ck avg min) */ MV_DDR_TAA_MIN, /* min cas latency time (t aa min) */

From: Chris Packham chris.packham@alliedtelesis.co.nz
Make ddr3_calc_mem_cs_size() global scope and use it in ddr3_new_tip_ecc_scrub to correctly initialize all of DDR memory.
Signed-off-by: Chris Packham judge.packham@gmail.com ---
Changes in v3: None Changes in v2: None
drivers/ddr/marvell/a38x/mv_ddr_plat.c | 2 +- drivers/ddr/marvell/a38x/mv_ddr_plat.h | 1 + drivers/ddr/marvell/a38x/xor.c | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_plat.c b/drivers/ddr/marvell/a38x/mv_ddr_plat.c index 2070bb38b099..2f318cb9ea7b 100644 --- a/drivers/ddr/marvell/a38x/mv_ddr_plat.c +++ b/drivers/ddr/marvell/a38x/mv_ddr_plat.c @@ -995,7 +995,7 @@ static u32 ddr3_get_device_size(u32 cs) } }
-static int ddr3_calc_mem_cs_size(u32 cs, uint64_t *cs_size) +int ddr3_calc_mem_cs_size(u32 cs, uint64_t *cs_size) { u32 cs_mem_size;
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_plat.h b/drivers/ddr/marvell/a38x/mv_ddr_plat.h index 61f10302fcca..9c5fdecd9341 100644 --- a/drivers/ddr/marvell/a38x/mv_ddr_plat.h +++ b/drivers/ddr/marvell/a38x/mv_ddr_plat.h @@ -232,4 +232,5 @@ u32 mv_ddr_dm_pad_get(void); int mv_ddr_pre_training_fixup(void); int mv_ddr_post_training_fixup(void); int mv_ddr_manual_cal_do(void); +int ddr3_calc_mem_cs_size(u32 cs, uint64_t *cs_size); #endif /* _MV_DDR_PLAT_H */ diff --git a/drivers/ddr/marvell/a38x/xor.c b/drivers/ddr/marvell/a38x/xor.c index 024cecd777c5..f859596d8953 100644 --- a/drivers/ddr/marvell/a38x/xor.c +++ b/drivers/ddr/marvell/a38x/xor.c @@ -347,6 +347,9 @@ void ddr3_new_tip_ecc_scrub(void) for (cs_c = 0; cs_c < max_cs; cs_c++) cs_ena |= 1 << cs_c;
+ /* assume that all CS have same size */ + ddr3_calc_mem_cs_size(0, &cs_mem_size); + mv_sys_xor_init(max_cs, cs_ena, cs_mem_size, 0); total_mem_size = max_cs * cs_mem_size; mv_xor_mem_init(0, 0, total_mem_size, 0xdeadbeef, 0xdeadbeef);

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