From ebb1a593252205114f6133b898f67473cc4c4899 Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Mon, 3 Dec 2018 14:26:49 +1300 Subject: [PATCH] ARM: mvebu: a38x: sync ddr training code with mv_ddr-armada-18.09.02 This syncs drivers/ddr/marvell/a38x/ with the mv_ddr-armada-18.09 branch of https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git. Specifically this syncs with commit 99d772547314 ("Bump mv_ddr to release armada-18.09.2"). The complete log of changes is best obtained from the mv-ddr-marvell.git repository but some relevant highlights are: ddr3: add missing txsdll parameter ddr3: fix tfaw timimg parameter ddr3: fix trrd timimg parameter merge ddr3 topology header file with mv_ddr_topology one mv_ddr: a38x: fix zero memory size scrubbing issue The upstream code is incorporated omitting the portions not relevant to Armada-38x and DDR3. 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 -UCONFIG_A3700 -UA3900 -UA80X0 \ -UA70X0 Signed-off-by: Chris Packham Reviewed-by: Stefan Roese Tested-by: Baruch Siach Signed-off-by: Stefan Roese --- board/CZ.NIC/turris_omnia/turris_omnia.c | 4 +- board/Marvell/db-88f6820-amc/db-88f6820-amc.c | 2 +- board/Marvell/db-88f6820-gp/db-88f6820-gp.c | 2 +- board/gdsys/a38x/controlcenterdc.c | 2 +- board/kobol/helios4/helios4.c | 2 +- board/solidrun/clearfog/clearfog.c | 2 +- drivers/ddr/marvell/a38x/ddr3_debug.c | 414 +-------------- drivers/ddr/marvell/a38x/ddr3_init.c | 91 +--- drivers/ddr/marvell/a38x/ddr3_init.h | 43 +- drivers/ddr/marvell/a38x/ddr3_topology_def.h | 78 --- drivers/ddr/marvell/a38x/ddr3_training.c | 484 +++++++++--------- drivers/ddr/marvell/a38x/ddr3_training_bist.c | 1 + .../a38x/ddr3_training_centralization.c | 3 + drivers/ddr/marvell/a38x/ddr3_training_db.c | 172 ++++--- .../ddr/marvell/a38x/ddr3_training_hw_algo.c | 1 + drivers/ddr/marvell/a38x/ddr3_training_ip.h | 38 -- .../ddr/marvell/a38x/ddr3_training_ip_def.h | 31 -- .../marvell/a38x/ddr3_training_ip_engine.c | 2 + .../marvell/a38x/ddr3_training_ip_engine.h | 1 + .../ddr/marvell/a38x/ddr3_training_ip_flow.h | 91 +--- .../marvell/a38x/ddr3_training_ip_prv_if.h | 10 +- .../ddr/marvell/a38x/ddr3_training_leveling.c | 75 +-- .../ddr/marvell/a38x/ddr3_training_leveling.h | 1 - drivers/ddr/marvell/a38x/ddr3_training_pbs.c | 7 +- drivers/ddr/marvell/a38x/ddr_topology_def.h | 107 +++- drivers/ddr/marvell/a38x/ddr_training_ip_db.h | 2 - drivers/ddr/marvell/a38x/dram_if.h | 13 + .../ddr/marvell/a38x/mv_ddr_build_message.c | 2 +- drivers/ddr/marvell/a38x/mv_ddr_common.h | 38 +- drivers/ddr/marvell/a38x/mv_ddr_plat.c | 181 ++++--- drivers/ddr/marvell/a38x/mv_ddr_plat.h | 12 +- drivers/ddr/marvell/a38x/mv_ddr_regs.h | 19 + drivers/ddr/marvell/a38x/mv_ddr_spd.c | 16 +- drivers/ddr/marvell/a38x/mv_ddr_topology.c | 215 ++++++-- drivers/ddr/marvell/a38x/mv_ddr_topology.h | 214 +++++++- drivers/ddr/marvell/a38x/mv_ddr_training_db.h | 40 ++ drivers/ddr/marvell/a38x/xor.c | 8 +- 37 files changed, 1163 insertions(+), 1261 deletions(-) delete mode 100644 drivers/ddr/marvell/a38x/ddr3_topology_def.h create mode 100644 drivers/ddr/marvell/a38x/dram_if.h create mode 100644 drivers/ddr/marvell/a38x/mv_ddr_training_db.h diff --git a/board/CZ.NIC/turris_omnia/turris_omnia.c b/board/CZ.NIC/turris_omnia/turris_omnia.c index 160d30cd79..1f7650cb36 100644 --- a/board/CZ.NIC/turris_omnia/turris_omnia.c +++ b/board/CZ.NIC/turris_omnia/turris_omnia.c @@ -212,7 +212,7 @@ static struct mv_ddr_topology_map board_topology_map_1g = { SPEED_BIN_DDR_1600K, /* speed_bin */ MV_DDR_DEV_WIDTH_16BIT, /* memory_width */ MV_DDR_DIE_CAP_4GBIT, /* mem_size */ - DDR_FREQ_800, /* frequency */ + MV_DDR_FREQ_800, /* frequency */ 0, 0, /* cas_wl cas_l */ MV_DDR_TEMP_NORMAL, /* temperature */ MV_DDR_TIM_2T} }, /* timing */ @@ -234,7 +234,7 @@ static struct mv_ddr_topology_map board_topology_map_2g = { SPEED_BIN_DDR_1600K, /* speed_bin */ MV_DDR_DEV_WIDTH_16BIT, /* memory_width */ MV_DDR_DIE_CAP_8GBIT, /* mem_size */ - DDR_FREQ_800, /* frequency */ + MV_DDR_FREQ_800, /* frequency */ 0, 0, /* cas_wl cas_l */ MV_DDR_TEMP_NORMAL, /* temperature */ MV_DDR_TIM_2T} }, /* timing */ diff --git a/board/Marvell/db-88f6820-amc/db-88f6820-amc.c b/board/Marvell/db-88f6820-amc/db-88f6820-amc.c index 92d7ae77f0..bc18fe6ddf 100644 --- a/board/Marvell/db-88f6820-amc/db-88f6820-amc.c +++ b/board/Marvell/db-88f6820-amc/db-88f6820-amc.c @@ -67,7 +67,7 @@ static struct mv_ddr_topology_map board_topology_map = { SPEED_BIN_DDR_1866L, /* speed_bin */ MV_DDR_DEV_WIDTH_8BIT, /* memory_width */ MV_DDR_DIE_CAP_2GBIT, /* mem_size */ - DDR_FREQ_800, /* frequency */ + MV_DDR_FREQ_800, /* frequency */ 0, 0, /* cas_wl cas_l */ MV_DDR_TEMP_LOW, /* temperature */ MV_DDR_TIM_DEFAULT} }, /* timing */ diff --git a/board/Marvell/db-88f6820-gp/db-88f6820-gp.c b/board/Marvell/db-88f6820-gp/db-88f6820-gp.c index a8cfe8af0a..9368bce26c 100644 --- a/board/Marvell/db-88f6820-gp/db-88f6820-gp.c +++ b/board/Marvell/db-88f6820-gp/db-88f6820-gp.c @@ -88,7 +88,7 @@ static struct mv_ddr_topology_map board_topology_map = { SPEED_BIN_DDR_1866L, /* speed_bin */ MV_DDR_DEV_WIDTH_8BIT, /* memory_width */ MV_DDR_DIE_CAP_4GBIT, /* mem_size */ - DDR_FREQ_800, /* frequency */ + MV_DDR_FREQ_800, /* frequency */ 0, 0, /* cas_wl cas_l */ MV_DDR_TEMP_LOW, /* temperature */ MV_DDR_TIM_DEFAULT} }, /* timing */ diff --git a/board/gdsys/a38x/controlcenterdc.c b/board/gdsys/a38x/controlcenterdc.c index dd4c083fbd..86051aedf8 100644 --- a/board/gdsys/a38x/controlcenterdc.c +++ b/board/gdsys/a38x/controlcenterdc.c @@ -64,7 +64,7 @@ static struct mv_ddr_topology_map ddr_topology_map = { SPEED_BIN_DDR_1600K, /* speed_bin */ MV_DDR_DEV_WIDTH_16BIT, /* memory_width */ MV_DDR_DIE_CAP_4GBIT, /* mem_size */ - DDR_FREQ_533, /* frequency */ + MV_DDR_FREQ_533, /* frequency */ 0, 0, /* cas_wl cas_l */ MV_DDR_TEMP_LOW, /* temperature */ MV_DDR_TIM_DEFAULT} }, /* timing */ diff --git a/board/kobol/helios4/helios4.c b/board/kobol/helios4/helios4.c index 341678319a..15e78dee94 100644 --- a/board/kobol/helios4/helios4.c +++ b/board/kobol/helios4/helios4.c @@ -78,7 +78,7 @@ static struct mv_ddr_topology_map board_topology_map = { SPEED_BIN_DDR_1600K, /* speed_bin */ MV_DDR_DEV_WIDTH_16BIT, /* memory_width */ MV_DDR_DIE_CAP_8GBIT, /* mem_size */ - DDR_FREQ_800, /* frequency */ + MV_DDR_FREQ_800, /* frequency */ 0, 0, /* cas_wl cas_l */ MV_DDR_TEMP_LOW, /* temperature */ MV_DDR_TIM_DEFAULT} }, /* timing */ diff --git a/board/solidrun/clearfog/clearfog.c b/board/solidrun/clearfog/clearfog.c index 4e1386c8a2..1742aa8921 100644 --- a/board/solidrun/clearfog/clearfog.c +++ b/board/solidrun/clearfog/clearfog.c @@ -65,7 +65,7 @@ static struct mv_ddr_topology_map board_topology_map = { SPEED_BIN_DDR_1600K, /* speed_bin */ MV_DDR_DEV_WIDTH_16BIT, /* memory_width */ MV_DDR_DIE_CAP_4GBIT, /* mem_size */ - DDR_FREQ_800, /* frequency */ + MV_DDR_FREQ_800, /* frequency */ 0, 0, /* cas_wl cas_l */ MV_DDR_TEMP_LOW, /* temperature */ MV_DDR_TIM_DEFAULT} }, /* timing */ diff --git a/drivers/ddr/marvell/a38x/ddr3_debug.c b/drivers/ddr/marvell/a38x/ddr3_debug.c index 1eac0bcd2b..f5fc964d6f 100644 --- a/drivers/ddr/marvell/a38x/ddr3_debug.c +++ b/drivers/ddr/marvell/a38x/ddr3_debug.c @@ -4,6 +4,8 @@ */ #include "ddr3_init.h" +#include "mv_ddr_training_db.h" +#include "mv_ddr_regs.h" u8 is_reg_dump = 0; u8 debug_pbs = DEBUG_LEVEL_ERROR; @@ -83,7 +85,7 @@ void ddr3_hws_set_log_level(enum ddr_lib_debug_block block, u8 level) #endif /* SILENT_LIB */ #if defined(DDR_VIEWER_TOOL) -static char *convert_freq(enum hws_ddr_freq freq); +static char *convert_freq(enum mv_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]; @@ -176,23 +178,6 @@ 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 */ @@ -218,50 +203,50 @@ int ddr3_tip_get_device_info(u32 dev_num, struct ddr3_device_info *info_ptr) /* * Convert freq to character string */ -static char *convert_freq(enum hws_ddr_freq freq) +static char *convert_freq(enum mv_ddr_freq freq) { switch (freq) { - case DDR_FREQ_LOW_FREQ: - return "DDR_FREQ_LOW_FREQ"; + case MV_DDR_FREQ_LOW_FREQ: + return "MV_DDR_FREQ_LOW_FREQ"; - case DDR_FREQ_400: + case MV_DDR_FREQ_400: return "400"; - case DDR_FREQ_533: + case MV_DDR_FREQ_533: return "533"; - case DDR_FREQ_667: + case MV_DDR_FREQ_667: return "667"; - case DDR_FREQ_800: + case MV_DDR_FREQ_800: return "800"; - case DDR_FREQ_933: + case MV_DDR_FREQ_933: return "933"; - case DDR_FREQ_1066: + case MV_DDR_FREQ_1066: return "1066"; - case DDR_FREQ_311: + case MV_DDR_FREQ_311: return "311"; - case DDR_FREQ_333: + case MV_DDR_FREQ_333: return "333"; - case DDR_FREQ_467: + case MV_DDR_FREQ_467: return "467"; - case DDR_FREQ_850: + case MV_DDR_FREQ_850: return "850"; - case DDR_FREQ_900: + case MV_DDR_FREQ_900: return "900"; - case DDR_FREQ_360: - return "DDR_FREQ_360"; + case MV_DDR_FREQ_360: + return "MV_DDR_FREQ_360"; - case DDR_FREQ_1000: - return "DDR_FREQ_1000"; + case MV_DDR_FREQ_1000: + return "MV_DDR_FREQ_1000"; default: return "Unknown Frequency"; @@ -364,7 +349,7 @@ int ddr3_tip_print_log(u32 dev_num, u32 mem_addr) if ((is_validate_window_per_if != 0) || (is_validate_window_per_pup != 0)) { u32 is_pup_log = 0; - enum hws_ddr_freq freq; + enum mv_ddr_freq freq; freq = tm->interface_params[first_active_if].memory_freq; @@ -528,7 +513,7 @@ 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 = ddr3_tip_max_cs_get(dev_num); + unsigned int max_cs = mv_ddr_cs_num_get(); struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); /* Title print */ @@ -844,8 +829,6 @@ u32 xsb_test_table[][8] = { 0xffffffff, 0xffffffff} }; -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; @@ -877,353 +860,6 @@ int ddr3_tip_print_adll(void) return MV_OK; } -/* - * Set attribute value - */ -int ddr3_tip_set_atr(u32 dev_num, u32 flag_id, u32 value) -{ - int ret; - u32 *ptr_flag = NULL; - - ret = ddr3_tip_access_atr(dev_num, flag_id, value, &ptr_flag); - if (ptr_flag != NULL) { - printf("ddr3_tip_set_atr Flag ID 0x%x value is set to 0x%x (was 0x%x)\n", - flag_id, value, *ptr_flag); - *ptr_flag = value; - } else { - printf("ddr3_tip_set_atr Flag ID 0x%x value is set to 0x%x\n", - flag_id, value); - } - - return ret; -} - -/* - * Access attribute - */ -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 mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); - - *ptr = NULL; - - switch (flag_id) { - case 0: - *ptr = (u32 *)&(tm->if_act_mask); - break; - - case 0x1: - *ptr = (u32 *)&mask_tune_func; - break; - - case 0x2: - low_freq = (enum hws_ddr_freq)value; - break; - - case 0x3: - medium_freq = (enum hws_ddr_freq)value; - break; - - case 0x4: - *ptr = (u32 *)&generic_init_controller; - break; - - case 0x8: - *ptr = (u32 *)&start_xsb_offset; - break; - - case 0x20: - *ptr = (u32 *)&is_rl_old; - break; - - case 0x21: - *ptr = (u32 *)&is_freq_old; - break; - - case 0x23: - *ptr = (u32 *)&is_dfs_disabled; - break; - - case 0x24: - *ptr = (u32 *)&is_pll_before_init; - break; - - case 0x25: - *ptr = (u32 *)&is_adll_calib_before_init; - break; - case 0x28: - *ptr = (u32 *)&is_tune_result; - break; - - case 0x29: - *ptr = (u32 *)&is_validate_window_per_if; - break; - - case 0x2a: - *ptr = (u32 *)&is_validate_window_per_pup; - break; - - case 0x30: - *ptr = (u32 *)&sweep_cnt; - break; - - case 0x31: - *ptr = (u32 *)&is_bist_reset_bit; - break; - - case 0x32: - *ptr = (u32 *)&is_dfs_in_init; - break; - - case 0x33: - *ptr = (u32 *)&g_zpodt_data; - break; - - case 0x34: - *ptr = (u32 *)&g_znodt_data; - break; - - case 0x35: - break; - - case 0x36: - *ptr = (u32 *)&(freq_val[DDR_FREQ_LOW_FREQ]); - break; - - case 0x37: - *ptr = (u32 *)&start_pattern; - break; - - case 0x38: - *ptr = (u32 *)&end_pattern; - break; - - case 0x39: - *ptr = (u32 *)&phy_reg0_val; - break; - - case 0x4a: - *ptr = (u32 *)&phy_reg1_val; - break; - - case 0x4b: - *ptr = (u32 *)&phy_reg2_val; - break; - - case 0x4c: - *ptr = (u32 *)&phy_reg3_val; - break; - - case 0x4e: - sweep_pattern = (enum hws_pattern)value; - break; - - case 0x51: - *ptr = (u32 *)&g_znri_data; - break; - - case 0x52: - *ptr = (u32 *)&g_zpri_data; - break; - - case 0x53: - *ptr = (u32 *)&finger_test; - break; - - case 0x54: - *ptr = (u32 *)&n_finger_start; - break; - - case 0x55: - *ptr = (u32 *)&n_finger_end; - break; - - case 0x56: - *ptr = (u32 *)&p_finger_start; - break; - - case 0x57: - *ptr = (u32 *)&p_finger_end; - break; - - case 0x58: - *ptr = (u32 *)&p_finger_step; - break; - - case 0x59: - *ptr = (u32 *)&n_finger_step; - break; - - case 0x5a: - *ptr = (u32 *)&g_znri_ctrl; - break; - - case 0x5b: - *ptr = (u32 *)&g_zpri_ctrl; - break; - - case 0x5c: - *ptr = (u32 *)&is_reg_dump; - break; - - case 0x5d: - *ptr = (u32 *)&vref_init_val; - break; - - case 0x5e: - *ptr = (u32 *)&mode_2t; - break; - - case 0x5f: - *ptr = (u32 *)&xsb_validate_type; - break; - - case 0x60: - *ptr = (u32 *)&xsb_validation_base_address; - break; - - case 0x67: - *ptr = (u32 *)&activate_select_before_run_alg; - break; - - case 0x68: - *ptr = (u32 *)&activate_deselect_after_run_alg; - break; - - case 0x69: - *ptr = (u32 *)&odt_additional; - break; - - case 0x70: - *ptr = (u32 *)&debug_mode; - break; - - case 0x71: - pbs_pattern = (enum hws_pattern)value; - break; - - case 0x72: - *ptr = (u32 *)&delay_enable; - break; - - case 0x73: - *ptr = (u32 *)&ck_delay; - break; - - case 0x75: - *ptr = (u32 *)&ca_delay; - break; - - case 0x100: - *ptr = (u32 *)&debug_dunit; - break; - - case 0x101: - debug_acc = (int)value; - break; - - case 0x102: - debug_training = (u8)value; - break; - - case 0x103: - debug_training_bist = (u8)value; - break; - - case 0x104: - debug_centralization = (u8)value; - break; - - case 0x105: - debug_training_ip = (u8)value; - break; - - case 0x106: - debug_leveling = (u8)value; - break; - - case 0x107: - debug_pbs = (u8)value; - break; - - case 0x108: - debug_training_static = (u8)value; - break; - - case 0x109: - debug_training_access = (u8)value; - break; - - - case 0x112: - *ptr = &start_pattern; - break; - - case 0x113: - *ptr = &end_pattern; - break; - - default: - if ((flag_id >= 0x200) && (flag_id < 0x210)) { - if_id = flag_id - 0x200; - *ptr = (u32 *)&(tm->interface_params - [if_id].memory_freq); - } else if ((flag_id >= 0x210) && (flag_id < 0x220)) { - if_id = flag_id - 0x210; - *ptr = (u32 *)&(tm->interface_params - [if_id].speed_bin_index); - } else if ((flag_id >= 0x220) && (flag_id < 0x230)) { - if_id = flag_id - 0x220; - *ptr = (u32 *)&(tm->interface_params - [if_id].bus_width); - } else if ((flag_id >= 0x230) && (flag_id < 0x240)) { - if_id = flag_id - 0x230; - *ptr = (u32 *)&(tm->interface_params - [if_id].memory_size); - } else if ((flag_id >= 0x240) && (flag_id < 0x250)) { - if_id = flag_id - 0x240; - *ptr = (u32 *)&(tm->interface_params - [if_id].cas_l); - } else if ((flag_id >= 0x250) && (flag_id < 0x260)) { - if_id = flag_id - 0x250; - *ptr = (u32 *)&(tm->interface_params - [if_id].cas_wl); - } else if ((flag_id >= 0x270) && (flag_id < 0x2cf)) { - if_id = (flag_id - 0x270) / MAX_BUS_NUM; - pup_id = (flag_id - 0x270) % MAX_BUS_NUM; - *ptr = (u32 *)&(tm->interface_params[if_id]. - as_bus_params[pup_id].is_ck_swap); - } else if ((flag_id >= 0x2d0) && (flag_id < 0x32f)) { - if_id = (flag_id - 0x2d0) / MAX_BUS_NUM; - pup_id = (flag_id - 0x2d0) % MAX_BUS_NUM; - *ptr = (u32 *)&(tm->interface_params[if_id]. - as_bus_params[pup_id].is_dqs_swap); - } else if ((flag_id >= 0x330) && (flag_id < 0x38f)) { - if_id = (flag_id - 0x330) / MAX_BUS_NUM; - pup_id = (flag_id - 0x330) % MAX_BUS_NUM; - *ptr = (u32 *)&(tm->interface_params[if_id]. - as_bus_params[pup_id].cs_bitmask); - } else if ((flag_id >= 0x390) && (flag_id < 0x3ef)) { - if_id = (flag_id - 0x390) / MAX_BUS_NUM; - pup_id = (flag_id - 0x390) % MAX_BUS_NUM; - *ptr = (u32 *)&(tm->interface_params - [if_id].as_bus_params - [pup_id].mirror_enable_bitmask); - } else if ((flag_id >= 0x500) && (flag_id <= 0x50f)) { - tmp_val = flag_id - 0x320; - *ptr = (u32 *)&(clamp_tbl[tmp_val]); - } else { - DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, - ("flag_id out of boundary %d\n", - flag_id)); - return MV_BAD_PARAM; - } - } - - return MV_OK; -} - #endif /* EXCLUDE_SWITCH_DEBUG */ #if defined(DDR_VIEWER_TOOL) @@ -1315,7 +951,7 @@ int ddr3_tip_run_sweep_test(int dev_num, u32 repeat_num, u32 direction, u32 reg; enum hws_access_type pup_access; u32 cs; - u32 max_cs = ddr3_tip_max_cs_get(dev_num); + unsigned int max_cs = mv_ddr_cs_num_get(); 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(); @@ -1462,7 +1098,7 @@ int ddr3_tip_run_leveling_sweep_test(int dev_num, u32 repeat_num, u32 reg; enum hws_access_type pup_access; u32 cs; - u32 max_cs = ddr3_tip_max_cs_get(dev_num); + unsigned int max_cs = mv_ddr_cs_num_get(); 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(); diff --git a/drivers/ddr/marvell/a38x/ddr3_init.c b/drivers/ddr/marvell/a38x/ddr3_init.c index 27dbf4f44b..22c8f9ca54 100644 --- a/drivers/ddr/marvell/a38x/ddr3_init.c +++ b/drivers/ddr/marvell/a38x/ddr3_init.c @@ -6,18 +6,6 @@ #include "ddr3_init.h" #include "mv_ddr_common.h" -/* - * 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_8GB -}; - static char *ddr_type = "DDR3"; /* @@ -37,8 +25,6 @@ static int mv_ddr_training_params_set(u8 dev_num); */ int ddr3_init(void) { - struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); - u32 octets_per_if_num; int status; int is_manual_cal_done; @@ -55,7 +41,7 @@ int ddr3_init(void) mv_ddr_early_init(); - if (mv_ddr_topology_map_update() == NULL) { + if (mv_ddr_topology_map_update()) { printf("mv_ddr: failed to update topology\n"); return MV_FAIL; } @@ -68,7 +54,6 @@ int ddr3_init(void) if (MV_OK != status) return status; - mv_ddr_mc_config(); is_manual_cal_done = mv_ddr_manual_cal_do(); @@ -101,76 +86,14 @@ int ddr3_init(void) mv_ddr_post_training_fixup(); - 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(); - } + if (mv_ddr_is_ecc_ena()) + mv_ddr_mem_scrubbing(); printf("mv_ddr: completed successfully\n"); return MV_OK; } -uint64_t mv_ddr_get_memory_size_per_cs_in_bits(void) -{ - uint64_t memory_size_per_cs; - - u32 bus_cnt, num_of_active_bus = 0; - u32 num_of_sub_phys_per_ddr_unit = 0; - - struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); - - u32 octets_per_if_num = ddr3_tip_dev_attr_get(DEV_NUM_0, MV_ATTR_OCTET_PER_INTERFACE); - - /* 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++; - } - - /* 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; - - /* 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 memory_size_per_cs; -} - -uint64_t mv_ddr_get_total_memory_size_in_bits(void) -{ - uint64_t total_memory_size = 0; - uint64_t memory_size_per_cs = 0; - - /* get the number of cs */ - u32 max_cs = ddr3_tip_max_cs_get(DEV_NUM_0); - - memory_size_per_cs = mv_ddr_get_memory_size_per_cs_in_bits(); - total_memory_size = (uint64_t)max_cs * memory_size_per_cs; - - return total_memory_size; -} - -int ddr3_if_ecc_enabled(void) -{ - struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); - - 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: mv_ddr_training_params_set * Desc: @@ -182,15 +105,9 @@ 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)); + cs_num = mv_ddr_cs_num_get(); /* NOTE: do not remove any field initilization */ params.ck_delay = TUNE_TRAINING_PARAMS_CK_DELAY; diff --git a/drivers/ddr/marvell/a38x/ddr3_init.h b/drivers/ddr/marvell/a38x/ddr3_init.h index 382bd922f2..055516b67e 100644 --- a/drivers/ddr/marvell/a38x/ddr3_init.h +++ b/drivers/ddr/marvell/a38x/ddr3_init.h @@ -7,9 +7,7 @@ #define _DDR3_INIT_H #include "ddr_ml_wrapper.h" -#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X) #include "mv_ddr_plat.h" -#endif #include "seq_exec.h" #include "ddr3_logging_def.h" @@ -32,14 +30,8 @@ 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, @@ -47,24 +39,26 @@ enum log_level { MV_LOG_LEVEL_3 }; +/* TODO: consider to move to misl phy driver */ +#define MISL_PHY_DRV_P_OFFS 0x7 +#define MISL_PHY_DRV_N_OFFS 0x0 +#define MISL_PHY_ODT_P_OFFS 0x6 +#define MISL_PHY_ODT_N_OFFS 0x0 + /* Globals */ 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; -/* list of allowed frequency listed in order of enum hws_ddr_freq */ -extern u32 freq_val[DDR_FREQ_LAST]; +/* list of allowed frequency listed in order of enum mv_ddr_freq */ 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_centralization, debug_training_ip, debug_training_bist, debug_pbs, debug_training_static, debug_leveling; extern struct hws_tip_config_func_db config_func_info[]; 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[]; @@ -90,10 +84,10 @@ 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 enum mv_ddr_freq medium_freq; extern enum hws_result training_result[MAX_STAGE_LIMIT][MAX_INTERFACE_NUM]; -extern enum hws_ddr_freq low_freq; +extern enum mv_ddr_freq low_freq; extern enum auto_tune_stage training_stage; extern u32 is_pll_before_init; extern u32 is_adll_calib_before_init; @@ -120,7 +114,7 @@ extern u32 odt_additional; extern u32 debug_mode; extern u32 debug_dunit; extern u32 clamp_tbl[]; -extern u32 freq_mask[MAX_DEVICE_NUM][DDR_FREQ_LAST]; +extern u32 freq_mask[MAX_DEVICE_NUM][MV_DDR_FREQ_LAST]; extern u32 maxt_poll_tries; extern u32 is_bist_reset_bit; @@ -139,7 +133,6 @@ extern u16 mask_results_dq_reg_map[]; extern u32 target_freq; extern u32 dfs_low_freq; -extern u32 mem_size[]; extern u32 nominal_avs; extern u32 extension_avs; @@ -154,13 +147,8 @@ 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 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); @@ -185,15 +173,20 @@ void get_target_freq(u32 freq_mode, u32 *ddr_freq, u32 *hclk_ps); void ddr3_fast_path_static_cs_size_config(u32 cs_ena); u32 mv_board_id_index_get(u32 board_id); void ddr3_set_log_level(u32 n_log_level); -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); - -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); +/* TODO: consider to move to misl phy driver */ +unsigned int mv_ddr_misl_phy_drv_data_p_get(void); +unsigned int mv_ddr_misl_phy_drv_data_n_get(void); +unsigned int mv_ddr_misl_phy_drv_ctrl_p_get(void); +unsigned int mv_ddr_misl_phy_drv_ctrl_n_get(void); +unsigned int mv_ddr_misl_phy_odt_p_get(void); +unsigned int mv_ddr_misl_phy_odt_n_get(void); + #endif /* _DDR3_INIT_H */ diff --git a/drivers/ddr/marvell/a38x/ddr3_topology_def.h b/drivers/ddr/marvell/a38x/ddr3_topology_def.h deleted file mode 100644 index 1963bae3e6..0000000000 --- a/drivers/ddr/marvell/a38x/ddr3_topology_def.h +++ /dev/null @@ -1,78 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (C) Marvell International Ltd. and its affiliates - */ - -#ifndef _DDR3_TOPOLOGY_DEF_H -#define _DDR3_TOPOLOGY_DEF_H - -#define DEV_NUM_0 0 - -/* TOPOLOGY */ -enum hws_speed_bin { - SPEED_BIN_DDR_800D, - SPEED_BIN_DDR_800E, - SPEED_BIN_DDR_1066E, - SPEED_BIN_DDR_1066F, - SPEED_BIN_DDR_1066G, - SPEED_BIN_DDR_1333F, - SPEED_BIN_DDR_1333G, - SPEED_BIN_DDR_1333H, - SPEED_BIN_DDR_1333J, - SPEED_BIN_DDR_1600G, - SPEED_BIN_DDR_1600H, - SPEED_BIN_DDR_1600J, - SPEED_BIN_DDR_1600K, - SPEED_BIN_DDR_1866J, - SPEED_BIN_DDR_1866K, - SPEED_BIN_DDR_1866L, - SPEED_BIN_DDR_1866M, - SPEED_BIN_DDR_2133K, - SPEED_BIN_DDR_2133L, - SPEED_BIN_DDR_2133M, - SPEED_BIN_DDR_2133N, - - SPEED_BIN_DDR_1333H_EXT, - SPEED_BIN_DDR_1600K_EXT, - SPEED_BIN_DDR_1866M_EXT -}; - -enum hws_ddr_freq { - DDR_FREQ_LOW_FREQ, - DDR_FREQ_400, - DDR_FREQ_533, - DDR_FREQ_667, - DDR_FREQ_800, - DDR_FREQ_933, - DDR_FREQ_1066, - DDR_FREQ_311, - DDR_FREQ_333, - DDR_FREQ_467, - DDR_FREQ_850, - DDR_FREQ_600, - DDR_FREQ_300, - DDR_FREQ_900, - DDR_FREQ_360, - DDR_FREQ_1000, - DDR_FREQ_LAST, - DDR_FREQ_SAR -}; - -enum speed_bin_table_elements { - SPEED_BIN_TRCD, - SPEED_BIN_TRP, - SPEED_BIN_TRAS, - SPEED_BIN_TRC, - SPEED_BIN_TRRD1K, - SPEED_BIN_TRRD2K, - SPEED_BIN_TPD, - SPEED_BIN_TFAW1K, - SPEED_BIN_TFAW2K, - SPEED_BIN_TWTR, - SPEED_BIN_TRTP, - SPEED_BIN_TWR, - SPEED_BIN_TMOD, - SPEED_BIN_TXPDLL -}; - -#endif /* _DDR3_TOPOLOGY_DEF_H */ diff --git a/drivers/ddr/marvell/a38x/ddr3_training.c b/drivers/ddr/marvell/a38x/ddr3_training.c index 799c5ba089..c7be700d64 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training.c +++ b/drivers/ddr/marvell/a38x/ddr3_training.c @@ -5,6 +5,8 @@ #include "ddr3_init.h" #include "mv_ddr_common.h" +#include "mv_ddr_training_db.h" +#include "mv_ddr_regs.h" #define GET_CS_FROM_MASK(mask) (cs_mask2_num[mask]) #define CS_CBE_VALUE(cs_num) (cs_cbe_reg[cs_num]) @@ -14,8 +16,8 @@ u32 phy_reg0_val = 0; u32 phy_reg1_val = 8; u32 phy_reg2_val = 0; u32 phy_reg3_val = PARAM_UNDEFINED; -enum hws_ddr_freq low_freq = DDR_FREQ_LOW_FREQ; -enum hws_ddr_freq medium_freq; +enum mv_ddr_freq low_freq = MV_DDR_FREQ_LOW_FREQ; +enum mv_ddr_freq medium_freq; u32 debug_dunit = 0; u32 odt_additional = 1; u32 *dq_map_table = NULL; @@ -97,36 +99,9 @@ static int odt_test(u32 dev_num, enum hws_algo_type algo_type); #endif int adll_calibration(u32 dev_num, enum hws_access_type access_type, - u32 if_id, enum hws_ddr_freq frequency); + u32 if_id, enum mv_ddr_freq frequency); 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_tbl[] = { - /* - * 8bits 16 bits - * page-size(K) page-size(K) mask - */ - { 1, 2, 2}, - /* 512M */ - { 1, 2, 3}, - /* 1G */ - { 1, 2, 0}, - /* 2G */ - { 1, 2, 4}, - /* 4G */ - { 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 */ - -}; - -struct page_element *mv_ddr_page_tbl_get(void) -{ - return &page_tbl[0]; -} + u32 if_id, enum mv_ddr_freq frequency); static u8 mem_size_config[MV_DDR_DIE_CAP_LAST] = { 0x2, /* 512Mbit */ @@ -204,7 +179,52 @@ struct mv_ddr_mr_data mr_data[] = { {MRS3_CMD, MR3_REG} }; -static int ddr3_tip_pad_inv(u32 dev_num, u32 if_id); +/* inverse pads */ +static int ddr3_tip_pad_inv(void) +{ + u32 sphy, data; + u32 sphy_max = ddr3_tip_dev_attr_get(0, MV_ATTR_OCTET_PER_INTERFACE); + u32 ck_swap_ctrl_sphy; + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + + for (sphy = 0; sphy < sphy_max; sphy++) { + VALIDATE_BUS_ACTIVE(tm->bus_act_mask, sphy); + if (tm->interface_params[0]. + as_bus_params[sphy].is_dqs_swap == 1) { + data = (INVERT_PAD << INV_PAD4_OFFS | + INVERT_PAD << INV_PAD5_OFFS); + /* dqs swap */ + ddr3_tip_bus_read_modify_write(0, ACCESS_TYPE_UNICAST, + 0, sphy, + DDR_PHY_DATA, + PHY_CTRL_PHY_REG, + data, data); + } + + if (tm->interface_params[0].as_bus_params[sphy]. + is_ck_swap == 1 && sphy == 0) { +/* TODO: move this code to per platform one */ +#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X) + /* clock swap for both cs0 and cs1 */ + data = (INVERT_PAD << INV_PAD2_OFFS | + INVERT_PAD << INV_PAD6_OFFS | + INVERT_PAD << INV_PAD4_OFFS | + INVERT_PAD << INV_PAD5_OFFS); + ck_swap_ctrl_sphy = CK_SWAP_CTRL_PHY_NUM; + ddr3_tip_bus_read_modify_write(0, ACCESS_TYPE_UNICAST, + 0, ck_swap_ctrl_sphy, + DDR_PHY_CONTROL, + PHY_CTRL_PHY_REG, + data, data); +#else /* !CONFIG_ARMADA_38X && !CONFIG_ARMADA_39X && !A70X0 && !A80X0 && !A3900 */ +#pragma message "unknown platform to configure ddr clock swap" +#endif + } + } + + return MV_OK; +} + static int ddr3_tip_rank_control(u32 dev_num, u32 if_id); /* @@ -244,6 +264,7 @@ int ddr3_tip_tune_training_params(u32 dev_num, 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, @@ -308,44 +329,6 @@ int ddr3_tip_configure_cs(u32 dev_num, u32 if_id, u32 cs_num, u32 enable) return MV_OK; } -/* - * Calculate number of CS - */ -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; - 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 < 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; - for (cs = 0; cs < MAX_CS_NUM; cs++) { - if ((cs_bitmask >> cs) & 1) - cs_count++; - } - - if (curr_cs_num == 0) { - curr_cs_num = cs_count; - } else if (cs_count != curr_cs_num) { - DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, - ("CS number is different per bus (IF %d BUS %d cs_num %d curr_cs_num %d)\n", - if_id, bus_cnt, cs_count, - curr_cs_num)); - return MV_NOT_SUPPORTED; - } - } - *cs_num = curr_cs_num; - - return MV_OK; -} - /* * Init Controller Flow */ @@ -356,7 +339,7 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_ 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 mv_ddr_speed_bin speed_bin_index = SPEED_BIN_DDR_2133N; u32 cs_mask = 0; u32 cl_value = 0, cwl_val = 0; u32 bus_cnt = 0, adll_tap = 0; @@ -364,8 +347,8 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_ u32 data_read[MAX_INTERFACE_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(); - enum hws_ddr_freq freq = tm->interface_params[0].memory_freq; enum mv_ddr_timing timing; + enum mv_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", @@ -403,7 +386,7 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_ speed_bin_index; /* t_ckclk is external clock */ - t_ckclk = (MEGA / freq_val[freq]); + t_ckclk = (MEGA / mv_ddr_freq_get(freq)); if (MV_DDR_IS_HALF_BUS_DRAM_MODE(tm->bus_act_mask, octets_per_if_num)) data_value = (0x4000 | 0 | 0x1000000) & ~(1 << 26); @@ -508,7 +491,7 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_ * configure them both: The Bust_width it\92s the * Memory Bus width \96 x8 or x16 */ - for (cs_cnt = 0; cs_cnt < NUM_OF_CS; cs_cnt++) { + for (cs_cnt = 0; cs_cnt < MAX_CS_NUM; cs_cnt++) { ddr3_tip_configure_cs(dev_num, if_id, cs_cnt, ((cs_mask & (1 << cs_cnt)) ? 1 : 0)); @@ -534,7 +517,7 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_ ("cl_value 0x%x cwl_val 0x%x\n", cl_value, cwl_val)); - t_wr = time_to_nclk(speed_bin_table + t_wr = time_to_nclk(mv_ddr_speed_bin_timing_get (speed_bin_index, SPEED_BIN_TWR), t_ckclk); @@ -612,8 +595,7 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_ 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)); + cs_num = mv_ddr_cs_num_get(); t2t = (cs_num == 1) ? 0 : 1; } @@ -666,9 +648,8 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_ 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) { - CHECK_STATUS(ddr3_tip_pad_inv(dev_num, if_id)); - } + if (init_cntr_prm->do_mrs_phy) + ddr3_tip_pad_inv(); /* Pad calibration control - disable */ CHECK_STATUS(ddr3_tip_if_write @@ -682,7 +663,7 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_ if (delay_enable != 0) { - adll_tap = MEGA / (freq_val[freq] * 64); + adll_tap = MEGA / (mv_ddr_freq_get(freq) * 64); ddr3_tip_cmd_addr_init_delay(dev_num, adll_tap); } @@ -787,48 +768,6 @@ static int ddr3_tip_rank_control(u32 dev_num, u32 if_id) 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; - 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 < 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_CTRL_PHY_REG, 0xc0, - 0xc0); - } - - if (tm->interface_params[if_id]. - as_bus_params[bus_cnt].is_ck_swap == 1) { - if (bus_cnt <= 1) - data_value = 0x5 << 2; - else - data_value = 0xa << 2; - - /* mask equals data */ - /* ck swap pup is only control pup #0 ! */ - ck_swap_pup_ctrl = 0; - ddr3_tip_bus_read_modify_write(dev_num, ACCESS_TYPE_UNICAST, - if_id, ck_swap_pup_ctrl, - DDR_PHY_CONTROL, - PHY_CTRL_PHY_REG, - data_value, data_value); - } - } - - return MV_OK; -} - /* * Algorithm Parameters Validation */ @@ -1182,7 +1121,7 @@ int ddr3_tip_bus_read_modify_write(u32 dev_num, enum hws_access_type access_type * ADLL Calibration */ int adll_calibration(u32 dev_num, enum hws_access_type access_type, - u32 if_id, enum hws_ddr_freq frequency) + u32 if_id, enum mv_ddr_freq frequency) { struct hws_tip_freq_config_info freq_config_info; u32 bus_cnt = 0; @@ -1229,7 +1168,7 @@ int adll_calibration(u32 dev_num, enum hws_access_type access_type, CHECK_STATUS(ddr3_tip_if_write (dev_num, access_type, if_id, DRAM_PHY_CFG_REG, 0, (0x80000000 | 0x40000000))); - mdelay(100 / (freq_val[frequency] / freq_val[DDR_FREQ_LOW_FREQ])); + mdelay(100 / (mv_ddr_freq_get(frequency)) / mv_ddr_freq_get(MV_DDR_FREQ_LOW_FREQ)); CHECK_STATUS(ddr3_tip_if_write (dev_num, access_type, if_id, DRAM_PHY_CFG_REG, (0x80000000 | 0x40000000), (0x80000000 | 0x40000000))); @@ -1255,7 +1194,7 @@ int adll_calibration(u32 dev_num, enum hws_access_type access_type, } int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type, - u32 if_id, enum hws_ddr_freq frequency) + u32 if_id, enum mv_ddr_freq frequency) { u32 cl_value = 0, cwl_value = 0, mem_mask = 0, val = 0, bus_cnt = 0, t_wr = 0, t_ckclk = 0, @@ -1263,7 +1202,7 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type, u32 end_if, start_if; u32 bus_index = 0; int is_dll_off = 0; - enum hws_speed_bin speed_bin_index = 0; + enum mv_ddr_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; @@ -1274,12 +1213,13 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type, 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; + u32 freq = mv_ddr_freq_get(frequency); DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE, ("dev %d access %d IF %d freq %d\n", dev_num, access_type, if_id, frequency)); - if (frequency == DDR_FREQ_LOW_FREQ) + if (frequency == MV_DDR_FREQ_LOW_FREQ) is_dll_off = 1; if (access_type == ACCESS_TYPE_MULTICAST) { start_if = 0; @@ -1318,7 +1258,7 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type, cwl_value = tm->interface_params[if_id].cas_wl; } else if (tm->cfg_src == MV_DDR_CFG_SPD) { - tclk = 1000000 / freq_val[frequency]; + tclk = 1000000 / freq; 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"); @@ -1330,11 +1270,8 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type, return MV_FAIL; } } else { - cl_value = - cas_latency_table[speed_bin_index].cl_val[frequency]; - cwl_value = - cas_write_latency_table[speed_bin_index]. - cl_val[frequency]; + cl_value = mv_ddr_cl_val_get(speed_bin_index, frequency); + cwl_value = mv_ddr_cwl_val_get(speed_bin_index, frequency); } DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE, @@ -1342,11 +1279,9 @@ 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_LAST; cnt_id++) { + for (cnt_id = 0; cnt_id < MV_DDR_FREQ_LAST; cnt_id++) { DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE, - ("%d ", - cas_latency_table[speed_bin_index]. - cl_val[cnt_id])); + ("%d ", mv_ddr_cl_val_get(speed_bin_index, cnt_id))); } DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE, ("\n")); @@ -1420,7 +1355,7 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type, 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)); + cs_num = mv_ddr_cs_num_get(); t2t = (cs_num == 1) ? 0 : 1; } @@ -1455,8 +1390,8 @@ 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_to_nclk(speed_bin_table + t_ckclk = (MEGA / freq); + t_wr = time_to_nclk(mv_ddr_speed_bin_timing_get (speed_bin_index, SPEED_BIN_TWR), t_ckclk); @@ -1517,7 +1452,7 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type, (dev_num, access_type, if_id, DRAM_PHY_CFG_REG, 0, (0x80000000 | 0x40000000))); - mdelay(100 / (freq_val[frequency] / freq_val[DDR_FREQ_LOW_FREQ])); + mdelay(100 / (freq / mv_ddr_freq_get(MV_DDR_FREQ_LOW_FREQ))); CHECK_STATUS(ddr3_tip_if_write (dev_num, access_type, if_id, DRAM_PHY_CFG_REG, (0x80000000 | 0x40000000), @@ -1544,7 +1479,7 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type, /* 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 = (is_dll_off == 1) ? 1000 : (MEGA / (freq_val[frequency] * 64)); + adll_tap = (is_dll_off == 1) ? 1000 : (MEGA / (freq * 64)); ddr3_tip_cmd_addr_init_delay(dev_num, adll_tap); } @@ -1682,7 +1617,7 @@ static int ddr3_tip_write_odt(u32 dev_num, enum hws_access_type access_type, * Set Timing values for training */ static int ddr3_tip_set_timing(u32 dev_num, enum hws_access_type access_type, - u32 if_id, enum hws_ddr_freq frequency) + u32 if_id, enum mv_ddr_freq frequency) { 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, @@ -1690,66 +1625,63 @@ static int ddr3_tip_set_timing(u32 dev_num, enum hws_access_type access_type, 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 mv_ddr_speed_bin speed_bin_index; 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(); + u32 freq = mv_ddr_freq_get(frequency); 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 == - 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]); + page_size = mv_ddr_page_size_get(tm->interface_params[if_id].bus_width, memory_size); + t_ckclk = (MEGA / freq); /* HCLK in[ps] */ - t_hclk = MEGA / (freq_val[frequency] / config_func_info[dev_num].tip_get_clock_ratio(frequency)); + t_hclk = MEGA / (freq / 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 = mv_ddr_speed_bin_timing_get(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 = mv_ddr_speed_bin_timing_get(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 = GET_MAX_VALUE(t_ckclk * 3, mv_ddr_speed_bin_timing_get(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 = GET_MAX_VALUE(t_ckclk * 10, mv_ddr_speed_bin_timing_get(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, + t_rrd = (page_size == 1) ? mv_ddr_speed_bin_timing_get(speed_bin_index, SPEED_BIN_TRRD1K) : - speed_bin_table(speed_bin_index, SPEED_BIN_TRRD2K); + mv_ddr_speed_bin_timing_get(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, + t_rtp = GET_MAX_VALUE(t_ckclk * 4, mv_ddr_speed_bin_timing_get(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, + t_wtr = GET_MAX_VALUE(t_ckclk * 4, mv_ddr_speed_bin_timing_get(speed_bin_index, SPEED_BIN_TWTR)); - t_ras = time_to_nclk(speed_bin_table(speed_bin_index, + t_ras = time_to_nclk(mv_ddr_speed_bin_timing_get(speed_bin_index, SPEED_BIN_TRAS), t_ckclk); - t_rcd = time_to_nclk(speed_bin_table(speed_bin_index, + t_rcd = time_to_nclk(mv_ddr_speed_bin_timing_get(speed_bin_index, SPEED_BIN_TRCD), t_ckclk); - t_rp = time_to_nclk(speed_bin_table(speed_bin_index, + t_rp = time_to_nclk(mv_ddr_speed_bin_timing_get(speed_bin_index, SPEED_BIN_TRP), t_ckclk); - t_wr = time_to_nclk(speed_bin_table(speed_bin_index, + t_wr = time_to_nclk(mv_ddr_speed_bin_timing_get(speed_bin_index, SPEED_BIN_TWR), 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_rfc = time_to_nclk(mv_ddr_rfc_get(memory_size) * 1000, t_ckclk); t_mod = time_to_nclk(t_mod, t_ckclk); /* SDRAM Timing Low */ @@ -1826,68 +1758,6 @@ static int ddr3_tip_set_timing(u32 dev_num, enum hws_access_type access_type, } -/* - * Mode Read - */ -int hws_ddr3_tip_mode_read(u32 dev_num, struct mode_info *mode_info) -{ - u32 ret; - - ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, - MR0_REG, mode_info->reg_mr0, MASK_ALL_BITS); - if (ret != MV_OK) - return ret; - - ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, - MR1_REG, mode_info->reg_mr1, MASK_ALL_BITS); - if (ret != MV_OK) - return ret; - - ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, - MR2_REG, mode_info->reg_mr2, MASK_ALL_BITS); - if (ret != MV_OK) - return ret; - - ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, - MR3_REG, mode_info->reg_mr2, MASK_ALL_BITS); - if (ret != MV_OK) - return ret; - - ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, - 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, - RD_DATA_RDY_DLYS_REG, mode_info->read_data_ready, - MASK_ALL_BITS); - if (ret != MV_OK) - return ret; - - return MV_OK; -} - -/* - * Get first active IF - */ -int ddr3_tip_get_first_active_if(u8 dev_num, u32 interface_mask, - u32 *interface_id) -{ - u32 if_id; - 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); - if (interface_mask & (1 << if_id)) { - *interface_id = if_id; - break; - } - } - - return MV_OK; -} - /* * Write CS Result */ @@ -2139,9 +2009,10 @@ static int ddr3_tip_ddr3_training_main_flow(u32 dev_num) int ret = MV_OK; int adll_bypass_flag = 0; u32 if_id; - u32 max_cs = ddr3_tip_max_cs_get(dev_num); + unsigned int max_cs = mv_ddr_cs_num_get(); 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_freq freq = tm->interface_params[0].memory_freq; + unsigned int *freq_tbl = mv_ddr_freq_tbl_get(); #ifdef DDR_VIEWER_TOOL if (debug_training == DEBUG_LEVEL_TRACE) { @@ -2157,7 +2028,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; - freq_val[DDR_FREQ_LOW_FREQ] = dfs_low_freq; + freq_tbl[MV_DDR_FREQ_LOW_FREQ] = dfs_low_freq; if (is_pll_before_init != 0) { for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) { @@ -2220,7 +2091,7 @@ static int ddr3_tip_ddr3_training_main_flow(u32 dev_num) DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("SET_LOW_FREQ_MASK_BIT %d\n", - freq_val[low_freq])); + freq_tbl[low_freq])); ret = ddr3_tip_freq_set(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, low_freq); if (is_reg_dump != 0) @@ -2281,7 +2152,7 @@ static int ddr3_tip_ddr3_training_main_flow(u32 dev_num) training_stage = SET_MEDIUM_FREQ; DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("SET_MEDIUM_FREQ_MASK_BIT %d\n", - freq_val[medium_freq])); + freq_tbl[medium_freq])); ret = ddr3_tip_freq_set(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, medium_freq); @@ -2299,7 +2170,7 @@ static int ddr3_tip_ddr3_training_main_flow(u32 dev_num) training_stage = WRITE_LEVELING; DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("WRITE_LEVELING_MASK_BIT\n")); - if ((rl_mid_freq_wa == 0) || (freq_val[medium_freq] == 533)) { + if ((rl_mid_freq_wa == 0) || (freq_tbl[medium_freq] == 533)) { ret = ddr3_tip_dynamic_write_leveling(dev_num, 0); } else { /* Use old WL */ @@ -2341,7 +2212,7 @@ static int ddr3_tip_ddr3_training_main_flow(u32 dev_num) training_stage = READ_LEVELING; DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("READ_LEVELING_MASK_BIT\n")); - if ((rl_mid_freq_wa == 0) || (freq_val[medium_freq] == 533)) { + if ((rl_mid_freq_wa == 0) || (freq_tbl[medium_freq] == 533)) { ret = ddr3_tip_dynamic_read_leveling(dev_num, medium_freq); } else { /* Use old RL */ @@ -2417,19 +2288,13 @@ static int ddr3_tip_ddr3_training_main_flow(u32 dev_num) training_stage = SET_TARGET_FREQ; DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("SET_TARGET_FREQ_MASK_BIT %d\n", - freq_val[tm-> + freq_tbl[tm-> interface_params[first_active_if]. memory_freq])); ret = ddr3_tip_freq_set(dev_num, ACCESS_TYPE_MULTICAST, 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) { @@ -2892,3 +2757,140 @@ int hws_ddr3_cs_base_adr_calc(u32 if_id, u32 cs, u32 *cs_base_addr) return MV_OK; } + +/* TODO: consider to move to misl phy driver */ +enum { + MISL_PHY_DRV_OHM_30 = 0xf, + MISL_PHY_DRV_OHM_48 = 0xa, + MISL_PHY_DRV_OHM_80 = 0x6, + MISL_PHY_DRV_OHM_120 = 0x4 +}; + +enum { + MISL_PHY_ODT_OHM_60 = 0x8, + MISL_PHY_ODT_OHM_80 = 0x6, + MISL_PHY_ODT_OHM_120 = 0x4, + MISL_PHY_ODT_OHM_240 = 0x2 +}; + +static unsigned int mv_ddr_misl_phy_drv_calc(unsigned int cfg) +{ + unsigned int val; + + switch (cfg) { + case MV_DDR_OHM_30: + val = MISL_PHY_DRV_OHM_30; + break; + case MV_DDR_OHM_48: + val = MISL_PHY_DRV_OHM_48; + break; + case MV_DDR_OHM_80: + val = MISL_PHY_DRV_OHM_80; + break; + case MV_DDR_OHM_120: + val = MISL_PHY_DRV_OHM_120; + break; + default: + val = PARAM_UNDEFINED; + } + + return val; +} + +static unsigned int mv_ddr_misl_phy_odt_calc(unsigned int cfg) +{ + unsigned int val; + + switch (cfg) { + case MV_DDR_OHM_60: + val = MISL_PHY_ODT_OHM_60; + break; + case MV_DDR_OHM_80: + val = MISL_PHY_ODT_OHM_80; + break; + case MV_DDR_OHM_120: + val = MISL_PHY_ODT_OHM_120; + break; + case MV_DDR_OHM_240: + val = MISL_PHY_ODT_OHM_240; + break; + default: + val = PARAM_UNDEFINED; + } + + return val; +} + +unsigned int mv_ddr_misl_phy_drv_data_p_get(void) +{ + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + unsigned int drv_data_p = mv_ddr_misl_phy_drv_calc(tm->edata.phy_edata.drv_data_p); + + if (drv_data_p == PARAM_UNDEFINED) + printf("error: %s: unsupported drv_data_p parameter found\n", __func__); + + return drv_data_p; +} + +unsigned int mv_ddr_misl_phy_drv_data_n_get(void) +{ + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + unsigned int drv_data_n = mv_ddr_misl_phy_drv_calc(tm->edata.phy_edata.drv_data_n); + + if (drv_data_n == PARAM_UNDEFINED) + printf("error: %s: unsupported drv_data_n parameter found\n", __func__); + + return drv_data_n; +} + +unsigned int mv_ddr_misl_phy_drv_ctrl_p_get(void) +{ + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + unsigned int drv_ctrl_p = mv_ddr_misl_phy_drv_calc(tm->edata.phy_edata.drv_ctrl_p); + + if (drv_ctrl_p == PARAM_UNDEFINED) + printf("error: %s: unsupported drv_ctrl_p parameter found\n", __func__); + + return drv_ctrl_p; +} + +unsigned int mv_ddr_misl_phy_drv_ctrl_n_get(void) +{ + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + unsigned int drv_ctrl_n = mv_ddr_misl_phy_drv_calc(tm->edata.phy_edata.drv_ctrl_n); + + if (drv_ctrl_n == PARAM_UNDEFINED) + printf("error: %s: unsupported drv_ctrl_n parameter found\n", __func__); + + return drv_ctrl_n; +} + +unsigned int mv_ddr_misl_phy_odt_p_get(void) +{ + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + unsigned int cs_num = mv_ddr_cs_num_get(); + unsigned int odt_p = PARAM_UNDEFINED; + + if (cs_num > 0 && cs_num <= MAX_CS_NUM) + odt_p = mv_ddr_misl_phy_odt_calc(tm->edata.phy_edata.odt_p[cs_num - 1]); + + if (odt_p == PARAM_UNDEFINED) + printf("error: %s: unsupported odt_p parameter found\n", __func__); + + return odt_p; +} + +unsigned int mv_ddr_misl_phy_odt_n_get(void) +{ + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + unsigned int cs_num = mv_ddr_cs_num_get(); + unsigned int odt_n = PARAM_UNDEFINED; + + if (cs_num > 0 && cs_num <= MAX_CS_NUM) + odt_n = mv_ddr_misl_phy_odt_calc(tm->edata.phy_edata.odt_n[cs_num - 1]); + + if (odt_n == PARAM_UNDEFINED) + printf("error: %s: unsupported odt_n parameter found\n", __func__); + + return odt_n; +} diff --git a/drivers/ddr/marvell/a38x/ddr3_training_bist.c b/drivers/ddr/marvell/a38x/ddr3_training_bist.c index e29b1713f9..d388a17291 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_bist.c +++ b/drivers/ddr/marvell/a38x/ddr3_training_bist.c @@ -4,6 +4,7 @@ */ #include "ddr3_init.h" +#include "mv_ddr_regs.h" static u32 bist_offset = 32; enum hws_pattern sweep_pattern = PATTERN_KILLER_DQ0; diff --git a/drivers/ddr/marvell/a38x/ddr3_training_centralization.c b/drivers/ddr/marvell/a38x/ddr3_training_centralization.c index 03e5c9fdce..648b37ef6f 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_centralization.c +++ b/drivers/ddr/marvell/a38x/ddr3_training_centralization.c @@ -4,6 +4,7 @@ */ #include "ddr3_init.h" +#include "mv_ddr_regs.h" #define VALIDATE_WIN_LENGTH(e1, e2, maxsize) \ (((e2) + 1 > (e1) + (u8)MIN_WINDOW_SIZE) && \ @@ -698,6 +699,8 @@ int ddr3_tip_print_centralization_result(u32 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(); + dev_num = dev_num; + 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++) { diff --git a/drivers/ddr/marvell/a38x/ddr3_training_db.c b/drivers/ddr/marvell/a38x/ddr3_training_db.c index c0089f67f2..111a8586c6 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_db.c +++ b/drivers/ddr/marvell/a38x/ddr3_training_db.c @@ -3,11 +3,16 @@ * Copyright (C) Marvell International Ltd. and its affiliates */ -#include "ddr3_init.h" +#include "ddr_ml_wrapper.h" + +#include "ddr3_training_ip_flow.h" +#include "mv_ddr_topology.h" +#include "mv_ddr_training_db.h" +#include "ddr3_training_ip_db.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 }; +enum mv_ddr_dev_attribute ddr_dev_attributes[MV_ATTR_LAST]; +int ddr_dev_attr_init_done = 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); @@ -20,28 +25,38 @@ 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_LAST] = { - 0, /*DDR_FREQ_LOW_FREQ */ - 400, /*DDR_FREQ_400, */ - 533, /*DDR_FREQ_533, */ - 666, /*DDR_FREQ_667, */ - 800, /*DDR_FREQ_800, */ - 933, /*DDR_FREQ_933, */ - 1066, /*DDR_FREQ_1066, */ - 311, /*DDR_FREQ_311, */ - 333, /*DDR_FREQ_333, */ - 467, /*DDR_FREQ_467, */ - 850, /*DDR_FREQ_850, */ - 600, /*DDR_FREQ_600 */ - 300, /*DDR_FREQ_300 */ - 900, /*DDR_FREQ_900 */ - 360, /*DDR_FREQ_360 */ - 1000 /*DDR_FREQ_1000 */ +/* List of allowed frequency listed in order of enum mv_ddr_freq */ +static unsigned int freq_val[MV_DDR_FREQ_LAST] = { + 0, /*MV_DDR_FREQ_LOW_FREQ */ + 400, /*MV_DDR_FREQ_400, */ + 533, /*MV_DDR_FREQ_533, */ + 666, /*MV_DDR_FREQ_667, */ + 800, /*MV_DDR_FREQ_800, */ + 933, /*MV_DDR_FREQ_933, */ + 1066, /*MV_DDR_FREQ_1066, */ + 311, /*MV_DDR_FREQ_311, */ + 333, /*MV_DDR_FREQ_333, */ + 467, /*MV_DDR_FREQ_467, */ + 850, /*MV_DDR_FREQ_850, */ + 600, /*MV_DDR_FREQ_600 */ + 300, /*MV_DDR_FREQ_300 */ + 900, /*MV_DDR_FREQ_900 */ + 360, /*MV_DDR_FREQ_360 */ + 1000 /*MV_DDR_FREQ_1000 */ }; -/* Table for CL values per frequency for each speed bin index */ -struct cl_val_per_freq cas_latency_table[] = { +unsigned int *mv_ddr_freq_tbl_get(void) +{ + return &freq_val[0]; +} + +u32 mv_ddr_freq_get(enum mv_ddr_freq freq) +{ + return freq_val[freq]; +} + +/* cas latency values per frequency for each speed bin index */ +static struct mv_ddr_cl_val_per_freq cl_table[] = { /* * 400M 667M 933M 311M 467M 600M 360 * 100M 533M 800M 1066M 333M 850M 900 @@ -97,8 +112,13 @@ struct cl_val_per_freq cas_latency_table[] = { { {6, 6, 7, 9, 11, 13, 0, 6, 6, 7, 13, 9, 6, 13, 6, 13} }, }; -/* Table for CWL values per speedbin index */ -struct cl_val_per_freq cas_write_latency_table[] = { +u32 mv_ddr_cl_val_get(u32 index, u32 freq) +{ + return cl_table[index].cl_val[freq]; +} + +/* cas write latency values per frequency for each speed bin index */ +static struct mv_ddr_cl_val_per_freq cwl_table[] = { /* * 400M 667M 933M 311M 467M 600M 360 * 100M 533M 800M 1066M 333M 850M 900 @@ -154,6 +174,11 @@ struct cl_val_per_freq cas_write_latency_table[] = { { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} }, }; +u32 mv_ddr_cwl_val_get(u32 index, u32 freq) +{ + return cwl_table[index].cl_val[freq]; +} + u8 twr_mask_table[] = { 10, 10, @@ -213,18 +238,23 @@ u8 cwl_mask_table[] = { }; /* RFC values (in ns) */ -u16 rfc_table[] = { - 90, /* 512M */ - 110, /* 1G */ - 160, /* 2G */ - 260, /* 4G */ - 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 */ +static unsigned int rfc_table[] = { + 90, /* 512M */ + 110, /* 1G */ + 160, /* 2G */ + 260, /* 4G */ + 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 mv_ddr_rfc_get(u32 mem) +{ + return rfc_table[mem]; +} + u32 speed_bin_table_t_rc[] = { 50000, 52500, @@ -358,8 +388,29 @@ static u8 pattern_vref_pattern_table_map[] = { 0xfe }; +static struct mv_ddr_page_element page_tbl[] = { + /* 8-bit, 16-bit page size */ + {MV_DDR_PAGE_SIZE_1K, MV_DDR_PAGE_SIZE_2K}, /* 512M */ + {MV_DDR_PAGE_SIZE_1K, MV_DDR_PAGE_SIZE_2K}, /* 1G */ + {MV_DDR_PAGE_SIZE_1K, MV_DDR_PAGE_SIZE_2K}, /* 2G */ + {MV_DDR_PAGE_SIZE_1K, MV_DDR_PAGE_SIZE_2K}, /* 4G */ + {MV_DDR_PAGE_SIZE_2K, MV_DDR_PAGE_SIZE_2K}, /* 8G */ + {0, 0}, /* TODO: placeholder for 16-Mbit die capacity */ + {0, 0}, /* TODO: placeholder for 32-Mbit die capacity */ + {0, 0}, /* TODO: placeholder for 12-Mbit die capacity */ + {0, 0} /* TODO: placeholder for 24-Mbit die capacity */ +}; + +u32 mv_ddr_page_size_get(enum mv_ddr_dev_width bus_width, enum mv_ddr_die_capacity mem_size) +{ + if (bus_width == MV_DDR_DEV_WIDTH_8BIT) + return page_tbl[mem_size].page_size_8bit; + else + return page_tbl[mem_size].page_size_16bit; +} + /* Return speed Bin value for selected index and t* element */ -u32 speed_bin_table(u8 index, enum speed_bin_table_elements element) +unsigned int mv_ddr_speed_bin_timing_get(enum mv_ddr_speed_bin index, enum mv_ddr_speed_bin_timing element) { u32 result = 0; @@ -384,19 +435,19 @@ 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 < SPEED_BIN_DDR_800E) + if (index <= SPEED_BIN_DDR_800E) result = 10000; - else if (index < SPEED_BIN_DDR_1066G) + else if (index <= SPEED_BIN_DDR_1066G) result = 7500; - else if (index < SPEED_BIN_DDR_1600K) + else if (index <= SPEED_BIN_DDR_1600K) result = 6000; else result = 5000; break; case SPEED_BIN_TRRD2K: - if (index < SPEED_BIN_DDR_1066G) + if (index <= SPEED_BIN_DDR_1066G) result = 10000; - else if (index < SPEED_BIN_DDR_1600K) + else if (index <= SPEED_BIN_DDR_1600K) result = 7500; else result = 6000; @@ -410,23 +461,23 @@ u32 speed_bin_table(u8 index, enum speed_bin_table_elements element) result = 5000; break; case SPEED_BIN_TFAW1K: - if (index < SPEED_BIN_DDR_800E) + if (index <= SPEED_BIN_DDR_800E) result = 40000; - else if (index < SPEED_BIN_DDR_1066G) + else if (index <= SPEED_BIN_DDR_1066G) result = 37500; - else if (index < SPEED_BIN_DDR_1600K) + else if (index <= SPEED_BIN_DDR_1600K) result = 30000; - else if (index < SPEED_BIN_DDR_1866M) + else if (index <= SPEED_BIN_DDR_1866M) result = 27000; else result = 25000; break; case SPEED_BIN_TFAW2K: - if (index < SPEED_BIN_DDR_1066G) + if (index <= SPEED_BIN_DDR_1066G) result = 50000; - else if (index < SPEED_BIN_DDR_1333J) + else if (index <= SPEED_BIN_DDR_1333J) result = 45000; - else if (index < SPEED_BIN_DDR_1600K) + else if (index <= SPEED_BIN_DDR_1600K) result = 40000; else result = 35000; @@ -446,6 +497,9 @@ u32 speed_bin_table(u8 index, enum speed_bin_table_elements element) case SPEED_BIN_TXPDLL: result = 24000; break; + case SPEED_BIN_TXSDLL: + result = 512; + break; default: break; } @@ -608,7 +662,7 @@ static inline u32 pattern_table_get_static_pbs_word(u8 index) u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index) { - u32 pattern; + u32 pattern = 0; struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask) == 0) { @@ -696,8 +750,8 @@ u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index) 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)); + printf("error: %s: unsupported pattern type [%d] found\n", + __func__, (int)type); pattern = 0; break; } @@ -779,8 +833,8 @@ u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index) 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)); + printf("error: %s: unsupported pattern type [%d] found\n", + __func__, (int)type); pattern = 0; break; } @@ -795,23 +849,23 @@ 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_attributes[attr_id] = 0xFF; - ddr_dev_attr_init_done[dev_num] = 1; + ddr_dev_attr_init_done = 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) + if (ddr_dev_attr_init_done == 0) ddr3_tip_dev_attr_init(dev_num); - return ddr_dev_attributes[dev_num][attr_id]; + return ddr_dev_attributes[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) + if (ddr_dev_attr_init_done == 0) ddr3_tip_dev_attr_init(dev_num); - ddr_dev_attributes[dev_num][attr_id] = value; + ddr_dev_attributes[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 6b8aae83d7..db0f8ad7fb 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_hw_algo.c +++ b/drivers/ddr/marvell/a38x/ddr3_training_hw_algo.c @@ -4,6 +4,7 @@ */ #include "ddr3_init.h" +#include "mv_ddr_regs.h" #define VREF_INITIAL_STEP 3 #define VREF_SECOND_STEP 1 diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip.h b/drivers/ddr/marvell/a38x/ddr3_training_ip.h index 531103c1ab..056c21497c 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_ip.h +++ b/drivers/ddr/marvell/a38x/ddr3_training_ip.h @@ -6,12 +6,8 @@ #ifndef _DDR3_TRAINING_IP_H_ #define _DDR3_TRAINING_IP_H_ -#include "ddr3_training_ip_def.h" #include "ddr_topology_def.h" -#include "ddr_training_ip_db.h" -#define MAX_CS_NUM 4 -#define MAX_TOTAL_BUS_NUM (MAX_INTERFACE_NUM * MAX_BUS_NUM) #define TIP_ENG_LOCK 0x02000000 #define TIP_TX_DLL_RANGE_MAX 64 @@ -112,40 +108,11 @@ struct pattern_info { u8 pattern_len; }; -/* CL value for each frequency */ -struct cl_val_per_freq { - u8 cl_val[DDR_FREQ_LAST]; -}; - struct cs_element { u8 cs_num; u8 num_of_cs; }; -struct mode_info { - /* 32 bits representing MRS bits */ - u32 reg_mr0[MAX_INTERFACE_NUM]; - u32 reg_mr1[MAX_INTERFACE_NUM]; - u32 reg_mr2[MAX_INTERFACE_NUM]; - u32 reg_m_r3[MAX_INTERFACE_NUM]; - /* - * Each element in array represent read_data_sample register delay for - * a specific interface. - * Each register, 4 bits[0+CS*8 to 4+CS*8] represent Number of DDR - * cycles from read command until data is ready to be fetched from - * the PHY, when accessing CS. - */ - u32 read_data_sample[MAX_INTERFACE_NUM]; - /* - * Each element in array represent read_data_sample register delay for - * a specific interface. - * Each register, 4 bits[0+CS*8 to 4+CS*8] represent the total delay - * from read command until opening the read mask, when accessing CS. - * This field defines the delay in DDR cycles granularity. - */ - u32 read_data_ready[MAX_INTERFACE_NUM]; -}; - struct hws_tip_freq_config_info { u8 is_supported; u8 bw_per_freq; @@ -173,12 +140,7 @@ int hws_ddr3_tip_init_controller(u32 dev_num, int hws_ddr3_tip_load_topology_map(u32 dev_num, 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_def.h b/drivers/ddr/marvell/a38x/ddr3_training_ip_def.h index 2318ceba29..2a68669f36 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_ip_def.h +++ b/drivers/ddr/marvell/a38x/ddr3_training_ip_def.h @@ -75,32 +75,6 @@ #define GET_RESULT_STATE(res) (res) #define SET_RESULT_STATE(res, state) (res = state) -#define _1K 0x00000400 -#define _4K 0x00001000 -#define _8K 0x00002000 -#define _16K 0x00004000 -#define _32K 0x00008000 -#define _64K 0x00010000 -#define _128K 0x00020000 -#define _256K 0x00040000 -#define _512K 0x00080000 - -#define _1M 0x00100000 -#define _2M 0x00200000 -#define _4M 0x00400000 -#define _8M 0x00800000 -#define _16M 0x01000000 -#define _32M 0x02000000 -#define _64M 0x04000000 -#define _128M 0x08000000 -#define _256M 0x10000000 -#define _512M 0x20000000 - -#define _1G 0x40000000 -#define _2G 0x80000000 -#define _4G 0x100000000 -#define _8G 0x200000000 - #define ADDR_SIZE_512MB 0x04000000 #define ADDR_SIZE_1GB 0x08000000 #define ADDR_SIZE_2GB 0x10000000 @@ -126,11 +100,6 @@ enum hws_search_dir { HWS_SEARCH_DIR_LIMIT }; -enum hws_page_size { - PAGE_SIZE_1K, - PAGE_SIZE_2K -}; - enum hws_operation { OPERATION_READ = 0, OPERATION_WRITE = 1 diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c b/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c index 334c2906fd..74417d61b4 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c +++ b/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c @@ -4,6 +4,8 @@ */ #include "ddr3_init.h" +#include "mv_ddr_regs.h" +#include "ddr_training_ip_db.h" #define PATTERN_1 0x55555555 #define PATTERN_2 0xaaaaaaaa diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.h b/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.h index 8fbcff50bb..2d40e68db8 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.h +++ b/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.h @@ -8,6 +8,7 @@ #include "ddr3_training_ip_def.h" #include "ddr3_training_ip_flow.h" +#include "ddr3_training_ip_pbs.h" #define EDGE_1 0 #define EDGE_2 1 diff --git a/drivers/ddr/marvell/a38x/ddr3_training_ip_flow.h b/drivers/ddr/marvell/a38x/ddr3_training_ip_flow.h index 6a9ef35f64..ab152cb455 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_ip_flow.h +++ b/drivers/ddr/marvell/a38x/ddr3_training_ip_flow.h @@ -7,71 +7,17 @@ #define _DDR3_TRAINING_IP_FLOW_H_ #include "ddr3_training_ip.h" -#include "ddr3_training_ip_pbs.h" -#include "mv_ddr_regs.h" +#include "ddr3_training_ip_db.h" #define KILLER_PATTERN_LENGTH 32 #define EXT_ACCESS_BURST_LENGTH 8 -#define IS_ACTIVE(mask, id) \ - ((mask) & (1 << (id))) - -#define VALIDATE_ACTIVE(mask, id) \ - { \ - if (IS_ACTIVE(mask, id) == 0) \ - continue; \ - } - -#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) == BUS_MASK_16BIT_ECC_PUP3) ? 1 : 0) - -#define DDR3_IS_ECC_PUP4_MODE(if_mask) \ - ((if_mask == BUS_MASK_32BIT_ECC || if_mask == BUS_MASK_16BIT_ECC) ? 1 : 0) - -#define DDR3_IS_16BIT_DRAM_MODE(mask) \ - ((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 @@ -92,8 +38,6 @@ */ /* nsec */ -#define TREFI_LOW 7800 -#define TREFI_HIGH 3900 #define AUTO_ZQC_TIMING 15384 enum mr_number { @@ -114,20 +58,11 @@ struct write_supp_result { int is_pup_fail; }; -struct page_element { - enum hws_page_size page_size_8bit; - /* page size in 8 bits bus width */ - enum hws_page_size page_size_16bit; - /* page size in 16 bits bus width */ - u32 ui_page_mask; - /* Mask used in register */ -}; - int ddr3_tip_write_leveling_static_config(u32 dev_num, u32 if_id, - enum hws_ddr_freq frequency, + enum mv_ddr_freq frequency, u32 *round_trip_delay_arr); int ddr3_tip_read_leveling_static_config(u32 dev_num, u32 if_id, - enum hws_ddr_freq frequency, + enum mv_ddr_freq frequency, u32 *total_round_trip_delay_arr); 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); @@ -149,7 +84,7 @@ int ddr3_tip_bus_write(u32 dev_num, enum hws_access_type e_interface_access, enum hws_ddr_phy e_phy_type, u32 reg_addr, u32 data_value); int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type e_access, u32 if_id, - enum hws_ddr_freq memory_freq); + enum mv_ddr_freq memory_freq); int ddr3_tip_adjust_dqs(u32 dev_num); int ddr3_tip_init_controller(u32 dev_num); int ddr3_tip_ext_read(u32 dev_num, u32 if_id, u32 reg_addr, @@ -174,22 +109,12 @@ int ddr3_tip_configure_odpg(u32 dev_num, enum hws_access_type access_type, u32 tx_burst_size, u32 rx_phases, 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, 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 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); +int ddr3_tip_read_pup_value(u32 dev_num, u32 pup_values[], int reg_addr, u32 mask); +int ddr3_tip_read_adll_value(u32 dev_num, u32 pup_values[], u32 reg_addr, u32 mask); +int ddr3_tip_write_adll_value(u32 dev_num, u32 pup_values[], u32 reg_addr); +int ddr3_tip_tune_training_params(u32 dev_num, struct tune_train_params *params); #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 f614d688c9..2df592e1b0 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_ip_prv_if.h +++ b/drivers/ddr/marvell/a38x/ddr3_training_ip_prv_if.h @@ -28,15 +28,15 @@ typedef int (*HWS_TIP_DUNIT_REG_WRITE_FUNC_PTR)( u8 dev_num, enum hws_access_type interface_access, u32 if_id, u32 offset, u32 data, u32 mask); typedef int (*HWS_TIP_GET_FREQ_CONFIG_INFO)( - u8 dev_num, enum hws_ddr_freq freq, + u8 dev_num, enum mv_ddr_freq freq, struct hws_tip_freq_config_info *freq_config_info); typedef int (*HWS_TIP_GET_DEVICE_INFO)( u8 dev_num, struct ddr3_device_info *info_ptr); typedef int (*HWS_GET_CS_CONFIG_FUNC_PTR)( u8 dev_num, u32 cs_mask, struct hws_cs_config_info *cs_info); typedef int (*HWS_SET_FREQ_DIVIDER_FUNC_PTR)( - u8 dev_num, u32 if_id, enum hws_ddr_freq freq); -typedef int (*HWS_GET_INIT_FREQ)(u8 dev_num, enum hws_ddr_freq *freq); + u8 dev_num, u32 if_id, enum mv_ddr_freq freq); +typedef int (*HWS_GET_INIT_FREQ)(u8 dev_num, enum mv_ddr_freq *freq); typedef int (*HWS_TRAINING_IP_IF_WRITE_FUNC_PTR)( u32 dev_num, enum hws_access_type access_type, u32 dunit_id, u32 reg_addr, u32 data, u32 mask); @@ -54,7 +54,7 @@ typedef int (*HWS_TRAINING_IP_ALGO_RUN_FUNC_PTR)( u32 dev_num, enum hws_algo_type algo_type); typedef int (*HWS_TRAINING_IP_SET_FREQ_FUNC_PTR)( u32 dev_num, enum hws_access_type access_type, u32 if_id, - enum hws_ddr_freq frequency); + enum mv_ddr_freq frequency); typedef int (*HWS_TRAINING_IP_INIT_CONTROLLER_FUNC_PTR)( u32 dev_num, struct init_cntr_param *init_cntr_prm); typedef int (*HWS_TRAINING_IP_PBS_RX_FUNC_PTR)(u32 dev_num); @@ -64,7 +64,7 @@ typedef int (*HWS_TRAINING_IP_SELECT_CONTROLLER_FUNC_PTR)( typedef int (*HWS_TRAINING_IP_TOPOLOGY_MAP_LOAD_FUNC_PTR)( 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, + u32 dev_num, enum mv_ddr_freq frequency, enum hws_static_config_type static_config_type, u32 if_id); typedef int (*HWS_TRAINING_IP_EXTERNAL_READ_PTR)( u32 dev_num, u32 if_id, u32 ddr_addr, u32 num_bursts, u32 *data); diff --git a/drivers/ddr/marvell/a38x/ddr3_training_leveling.c b/drivers/ddr/marvell/a38x/ddr3_training_leveling.c index 6248ffc3fb..7f7df6794a 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_leveling.c +++ b/drivers/ddr/marvell/a38x/ddr3_training_leveling.c @@ -4,6 +4,9 @@ */ #include "ddr3_init.h" +#include "mv_ddr_training_db.h" +#include "ddr_training_ip_db.h" +#include "mv_ddr_regs.h" #define WL_ITERATION_NUM 10 @@ -24,33 +27,6 @@ static int ddr3_tip_wl_supp_align_phase_shift(u32 dev_num, u32 if_id, static int ddr3_tip_xsb_compare_test(u32 dev_num, u32 if_id, u32 bus_id, u32 edge_offset); -u32 ddr3_tip_max_cs_get(u32 dev_num) -{ - u32 c_cs, if_id, bus_id; - static u32 max_cs; - 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[if_id].as_bus_params[bus_id]. - cs_bitmask, c_cs); - max_cs++; - } - } - - return max_cs; -} - enum { PASS, FAIL @@ -61,20 +37,20 @@ Dynamic read leveling int ddr3_tip_dynamic_read_leveling(u32 dev_num, u32 freq) { u32 data, mask; - u32 max_cs = ddr3_tip_max_cs_get(dev_num); + unsigned int max_cs = mv_ddr_cs_num_get(); u32 bus_num, if_id, cl_val; - enum hws_speed_bin speed_bin_index; + enum mv_ddr_speed_bin speed_bin_index; /* save current CS value */ u32 cs_enable_reg_val[MAX_INTERFACE_NUM] = { 0 }; int is_any_pup_fail = 0; u32 data_read[MAX_INTERFACE_NUM + 1] = { 0 }; - u8 rl_values[NUM_OF_CS][MAX_BUS_NUM][MAX_INTERFACE_NUM]; + u8 rl_values[MAX_CS_NUM][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(); 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 (effective_cs = 0; effective_cs < NUM_OF_CS; effective_cs++) + for (effective_cs = 0; effective_cs < MAX_CS_NUM; 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++) rl_values[effective_cs][bus_num][if_id] = 0; @@ -143,8 +119,7 @@ int ddr3_tip_dynamic_read_leveling(u32 dev_num, u32 freq) VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id); speed_bin_index = tm->interface_params[if_id].speed_bin_index; - cl_val = - cas_latency_table[speed_bin_index].cl_val[freq]; + cl_val = mv_ddr_cl_val_get(speed_bin_index, freq); data = (cl_val << 17) | (0x3 << 25); mask = (0xff << 9) | (0x1f << 17) | (0x3 << 25); CHECK_STATUS(ddr3_tip_if_write @@ -340,7 +315,7 @@ 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 = ddr3_tip_max_cs_get(dev_num); + unsigned int max_cs = mv_ddr_cs_num_get(); struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); /* @@ -381,7 +356,7 @@ 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 = ddr3_tip_max_cs_get(dev_num); + unsigned int max_cs = mv_ddr_cs_num_get(); struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); /* @@ -426,7 +401,7 @@ int ddr3_tip_dynamic_per_bit_read_leveling(u32 dev_num, u32 freq) u32 curr_numb, curr_min_delay; int adll_array[3] = { 0, -0xa, 0x14 }; u32 phyreg3_arr[MAX_INTERFACE_NUM][MAX_BUS_NUM]; - enum hws_speed_bin speed_bin_index; + enum mv_ddr_speed_bin speed_bin_index; int is_any_pup_fail = 0; int break_loop = 0; u32 cs_enable_reg_val[MAX_INTERFACE_NUM]; /* save current CS value */ @@ -516,8 +491,7 @@ int ddr3_tip_dynamic_per_bit_read_leveling(u32 dev_num, u32 freq) VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id); speed_bin_index = tm->interface_params[if_id].speed_bin_index; - cl_val = - cas_latency_table[speed_bin_index].cl_val[freq]; + cl_val = mv_ddr_cl_val_get(speed_bin_index, freq); data = (cl_val << 17) | (0x3 << 25); mask = (0xff << 9) | (0x1f << 17) | (0x3 << 25); CHECK_STATUS(ddr3_tip_if_write @@ -839,10 +813,10 @@ int ddr3_tip_dynamic_write_leveling(u32 dev_num, int phase_remove) u32 res_values[MAX_INTERFACE_NUM * MAX_BUS_NUM] = { 0 }; u32 test_res = 0; /* 0 - success for all pup */ u32 data_read[MAX_INTERFACE_NUM]; - u8 wl_values[NUM_OF_CS][MAX_BUS_NUM][MAX_INTERFACE_NUM]; + u8 wl_values[MAX_CS_NUM][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 = ddr3_tip_max_cs_get(dev_num); + unsigned int max_cs = mv_ddr_cs_num_get(); 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(); @@ -1694,9 +1668,11 @@ enum rl_dqs_burst_state { 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 rl_dqs_burst_state rl_state[MAX_CS_NUM][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; @@ -1707,17 +1683,18 @@ int mv_ddr_rl_dqs_burst(u32 dev_num, u32 if_id, u32 freq) 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]; + unsigned int max_cs = mv_ddr_cs_num_get(); + u32 rl_values[MAX_CS_NUM][MAX_BUS_NUM][MAX_INTERFACE_NUM] = { { {0} } }; + u32 rl_min_values[MAX_CS_NUM][MAX_BUS_NUM][MAX_INTERFACE_NUM] = { { {0} } }; + u32 rl_max_values[MAX_CS_NUM][MAX_BUS_NUM][MAX_INTERFACE_NUM] = { { {0} } }; + u32 rl_val, rl_min_val[MAX_CS_NUM], rl_max_val[MAX_CS_NUM]; u32 reg_val_low, reg_val_high; - u32 reg_val, reg_mask; + u32 reg_val, reg_mask; uintptr_t test_addr = TEST_ADDR; + /* initialization */ - if (ddr3_if_ecc_enabled()) { + if (mv_ddr_is_ecc_ena()) { 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) | @@ -1753,6 +1730,7 @@ int mv_ddr_rl_dqs_burst(u32 dev_num, u32 if_id, u32 freq) /* 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, @@ -1972,6 +1950,7 @@ int mv_ddr_rl_dqs_burst(u32 dev_num, u32 if_id, u32 freq) 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, diff --git a/drivers/ddr/marvell/a38x/ddr3_training_leveling.h b/drivers/ddr/marvell/a38x/ddr3_training_leveling.h index 96d945a33d..6719fb83f5 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_leveling.h +++ b/drivers/ddr/marvell/a38x/ddr3_training_leveling.h @@ -11,6 +11,5 @@ 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 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 0511026afb..b7dfebd93c 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_pbs.c +++ b/drivers/ddr/marvell/a38x/ddr3_training_pbs.c @@ -4,6 +4,9 @@ */ #include "ddr3_init.h" +#include "mv_ddr_training_db.h" +#include "mv_ddr_common.h" +#include "mv_ddr_regs.h" #define TYPICAL_PBS_VALUE 12 @@ -33,7 +36,7 @@ static u8 pup_state[MAX_INTERFACE_NUM][MAX_BUS_NUM]; int ddr3_tip_pbs(u32 dev_num, enum pbs_dir pbs_mode) { u32 res0[MAX_INTERFACE_NUM]; - int adll_tap = MEGA / freq_val[medium_freq] / 64; + int adll_tap = MEGA / mv_ddr_freq_get(medium_freq) / 64; int pad_num = 0; enum hws_search_dir search_dir = (pbs_mode == PBS_RX_MODE) ? HWS_HIGH2LOW : HWS_LOW2HIGH; @@ -921,7 +924,7 @@ int ddr3_tip_pbs_tx(u32 uidev_num) int ddr3_tip_print_all_pbs_result(u32 dev_num) { u32 curr_cs; - u32 max_cs = ddr3_tip_max_cs_get(dev_num); + unsigned int max_cs = mv_ddr_cs_num_get(); for (curr_cs = 0; curr_cs < max_cs; curr_cs++) { ddr3_tip_print_pbs_result(dev_num, curr_cs, PBS_RX_MODE); diff --git a/drivers/ddr/marvell/a38x/ddr_topology_def.h b/drivers/ddr/marvell/a38x/ddr_topology_def.h index 812224909a..e6fe8a0428 100644 --- a/drivers/ddr/marvell/a38x/ddr_topology_def.h +++ b/drivers/ddr/marvell/a38x/ddr_topology_def.h @@ -7,16 +7,13 @@ #define _DDR_TOPOLOGY_DEF_H #include "ddr3_training_ip_def.h" -#include "ddr3_topology_def.h" - -#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X) -#include "mv_ddr_plat.h" -#endif - #include "mv_ddr_topology.h" #include "mv_ddr_spd.h" #include "ddr3_logging_def.h" +#define MV_DDR_MAX_BUS_NUM 9 +#define MV_DDR_MAX_IFACE_NUM 1 + struct bus_params { /* Chip Select (CS) bitmask (bits 0-CS0, bit 1- CS1 ...) */ u8 cs_bitmask; @@ -36,10 +33,10 @@ struct bus_params { struct if_params { /* bus configuration */ - struct bus_params as_bus_params[MAX_BUS_NUM]; + struct bus_params as_bus_params[MV_DDR_MAX_BUS_NUM]; /* Speed Bin Table */ - enum hws_speed_bin speed_bin_index; + enum mv_ddr_speed_bin speed_bin_index; /* sdram device width */ enum mv_ddr_dev_width bus_width; @@ -48,7 +45,7 @@ struct if_params { enum mv_ddr_die_capacity memory_size; /* The DDR frequency for each interfaces */ - enum hws_ddr_freq memory_freq; + enum mv_ddr_freq memory_freq; /* * delay CAS Write Latency @@ -69,6 +66,37 @@ struct if_params { enum mv_ddr_timing timing; }; +/* memory electrical configuration */ +struct mv_ddr_mem_edata { + enum mv_ddr_rtt_nom_park_evalue rtt_nom; + enum mv_ddr_rtt_nom_park_evalue rtt_park[MAX_CS_NUM]; + enum mv_ddr_rtt_wr_evalue rtt_wr[MAX_CS_NUM]; + enum mv_ddr_dic_evalue dic; +}; + +/* phy electrical configuration */ +struct mv_ddr_phy_edata { + enum mv_ddr_ohm_evalue drv_data_p; + enum mv_ddr_ohm_evalue drv_data_n; + enum mv_ddr_ohm_evalue drv_ctrl_p; + enum mv_ddr_ohm_evalue drv_ctrl_n; + enum mv_ddr_ohm_evalue odt_p[MAX_CS_NUM]; + enum mv_ddr_ohm_evalue odt_n[MAX_CS_NUM]; +}; + +/* mac electrical configuration */ +struct mv_ddr_mac_edata { + enum mv_ddr_odt_cfg_evalue odt_cfg_pat; + enum mv_ddr_odt_cfg_evalue odt_cfg_wr; + enum mv_ddr_odt_cfg_evalue odt_cfg_rd; +}; + +struct mv_ddr_edata { + struct mv_ddr_mem_edata mem_edata; + struct mv_ddr_phy_edata phy_edata; + struct mv_ddr_mac_edata mac_edata; +}; + struct mv_ddr_topology_map { /* debug level configuration */ enum mv_ddr_debug_level debug_level; @@ -77,7 +105,7 @@ struct mv_ddr_topology_map { u8 if_act_mask; /* Controller configuration per interface */ - struct if_params interface_params[MAX_INTERFACE_NUM]; + struct if_params interface_params[MV_DDR_MAX_IFACE_NUM]; /* Bit mask for active buses */ u16 bus_act_mask; @@ -90,8 +118,67 @@ struct mv_ddr_topology_map { /* timing parameters */ unsigned int timing_data[MV_DDR_TDATA_LAST]; + + /* electrical configuration */ + struct mv_ddr_edata edata; + + /* electrical parameters */ + unsigned int electrical_data[MV_DDR_EDATA_LAST]; +}; + +enum mv_ddr_iface_mode { + MV_DDR_RAR_ENA, + MV_DDR_RAR_DIS, }; +enum mv_ddr_iface_state { + MV_DDR_IFACE_NRDY, /* not ready */ + MV_DDR_IFACE_INIT, /* init'd */ + MV_DDR_IFACE_RDY, /* ready */ + MV_DDR_IFACE_DNE /* does not exist */ +}; + +enum mv_ddr_validation { + MV_DDR_VAL_DIS, + MV_DDR_VAL_RX, + MV_DDR_VAL_TX, + MV_DDR_VAL_RX_TX +}; + +struct mv_ddr_iface { + /* base addr of ap ddr interface belongs to */ + unsigned int ap_base; + + /* ddr interface id */ + unsigned int id; + + /* ddr interface state */ + enum mv_ddr_iface_state state; + + /* ddr interface mode (rar enabled/disabled) */ + enum mv_ddr_iface_mode iface_mode; + + /* ddr interface base address */ + unsigned long long iface_base_addr; + + /* ddr interface size - ddr flow will update this parameter */ + unsigned long long iface_byte_size; + + /* ddr i2c spd data address */ + unsigned int spd_data_addr; + + /* ddr i2c spd page 0 select address */ + unsigned int spd_page_sel_addr; + + /* ddr interface validation mode */ + enum mv_ddr_validation validation; + + /* ddr interface topology map */ + struct mv_ddr_topology_map tm; +}; + +struct mv_ddr_iface *mv_ddr_iface_get(void); + /* DDR3 training global configuration parameters */ struct tune_train_params { u32 ck_delay; diff --git a/drivers/ddr/marvell/a38x/ddr_training_ip_db.h b/drivers/ddr/marvell/a38x/ddr_training_ip_db.h index e7de5aef0c..f1b4d8efc0 100644 --- a/drivers/ddr/marvell/a38x/ddr_training_ip_db.h +++ b/drivers/ddr/marvell/a38x/ddr_training_ip_db.h @@ -6,10 +6,8 @@ #ifndef _DDR_TRAINING_IP_DB_H_ #define _DDR_TRAINING_IP_DB_H_ -#include "ddr_topology_def.h" #include "ddr3_training_ip_db.h" -u32 speed_bin_table(u8 index, enum speed_bin_table_elements element); u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index); #endif /* _DDR3_TRAINING_IP_DB_H_ */ diff --git a/drivers/ddr/marvell/a38x/dram_if.h b/drivers/ddr/marvell/a38x/dram_if.h new file mode 100644 index 0000000000..4d0846489b --- /dev/null +++ b/drivers/ddr/marvell/a38x/dram_if.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2016 Marvell International Ltd. + */ + +#ifndef _DRAM_IF_H_ +#define _DRAM_IF_H_ + +/* TODO: update atf to this new prototype */ +int dram_init(void); +void dram_mmap_config(void); +unsigned long long dram_iface_mem_sz_get(void); +#endif /* _DRAM_IF_H_ */ diff --git a/drivers/ddr/marvell/a38x/mv_ddr_build_message.c b/drivers/ddr/marvell/a38x/mv_ddr_build_message.c index 2b49b77f73..cc6234fd40 100644 --- a/drivers/ddr/marvell/a38x/mv_ddr_build_message.c +++ b/drivers/ddr/marvell/a38x/mv_ddr_build_message.c @@ -1,3 +1,3 @@ // SPDX-License-Identifier: GPL-2.0 const char mv_ddr_build_message[] = ""; -const char mv_ddr_version_string[] = "mv_ddr: mv_ddr-armada-17.10.4"; +const char mv_ddr_version_string[] = "mv_ddr: mv_ddr-armada-18.09.2"; diff --git a/drivers/ddr/marvell/a38x/mv_ddr_common.h b/drivers/ddr/marvell/a38x/mv_ddr_common.h index c71ff442ed..321a390c0d 100644 --- a/drivers/ddr/marvell/a38x/mv_ddr_common.h +++ b/drivers/ddr/marvell/a38x/mv_ddr_common.h @@ -9,10 +9,44 @@ 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 _1K 0x00000400 +#define _4K 0x00001000 +#define _8K 0x00002000 +#define _16K 0x00004000 +#define _32K 0x00008000 +#define _64K 0x00010000 +#define _128K 0x00020000 +#define _256K 0x00040000 +#define _512K 0x00080000 + +#define _1M 0x00100000 +#define _2M 0x00200000 +#define _4M 0x00400000 +#define _8M 0x00800000 +#define _16M 0x01000000 +#define _32M 0x02000000 +#define _64M 0x04000000 +#define _128M 0x08000000 +#define _256M 0x10000000 +#define _512M 0x20000000 + +#define _1G 0x40000000 +#define _2G 0x80000000 +#define _4G 0x100000000 +#define _8G 0x200000000 +#define _16G 0x400000000 +#define _32G 0x800000000 +#define _64G 0x1000000000 +#define _128G 0x2000000000 + +#define MEGA 1000000 +#define MV_DDR_MEGABYTE (1024 * 1024) #define MV_DDR_32_BITS_MASK 0xffffffff +#define GET_MAX_VALUE(x, y) \ + (((x) > (y)) ? (x) : (y)) + +void mv_ddr_ver_print(void); 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); diff --git a/drivers/ddr/marvell/a38x/mv_ddr_plat.c b/drivers/ddr/marvell/a38x/mv_ddr_plat.c index 2f318cb9ea..19e95d275a 100644 --- a/drivers/ddr/marvell/a38x/mv_ddr_plat.c +++ b/drivers/ddr/marvell/a38x/mv_ddr_plat.c @@ -1,10 +1,7 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (C) Marvell International Ltd. and its affiliates - */ #include "ddr3_init.h" - +#include "mv_ddr_training_db.h" +#include "mv_ddr_regs.h" #include "mv_ddr_sys_env_lib.h" #define DDR_INTERFACES_NUM 1 @@ -58,42 +55,42 @@ 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_bw_per_freq[MV_DDR_FREQ_LAST] = { + 0x3, /* MV_DDR_FREQ_100 */ + 0x4, /* MV_DDR_FREQ_400 */ + 0x4, /* MV_DDR_FREQ_533 */ + 0x5, /* MV_DDR_FREQ_667 */ + 0x5, /* MV_DDR_FREQ_800 */ + 0x5, /* MV_DDR_FREQ_933 */ + 0x5, /* MV_DDR_FREQ_1066 */ + 0x3, /* MV_DDR_FREQ_311 */ + 0x3, /* MV_DDR_FREQ_333 */ + 0x4, /* MV_DDR_FREQ_467 */ + 0x5, /* MV_DDR_FREQ_850 */ + 0x5, /* MV_DDR_FREQ_600 */ + 0x3, /* MV_DDR_FREQ_300 */ + 0x5, /* MV_DDR_FREQ_900 */ + 0x3, /* MV_DDR_FREQ_360 */ + 0x5 /* MV_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 u8 a38x_rate_per_freq[MV_DDR_FREQ_LAST] = { + 0x1, /* MV_DDR_FREQ_100 */ + 0x2, /* MV_DDR_FREQ_400 */ + 0x2, /* MV_DDR_FREQ_533 */ + 0x2, /* MV_DDR_FREQ_667 */ + 0x2, /* MV_DDR_FREQ_800 */ + 0x3, /* MV_DDR_FREQ_933 */ + 0x3, /* MV_DDR_FREQ_1066 */ + 0x1, /* MV_DDR_FREQ_311 */ + 0x1, /* MV_DDR_FREQ_333 */ + 0x2, /* MV_DDR_FREQ_467 */ + 0x2, /* MV_DDR_FREQ_850 */ + 0x2, /* MV_DDR_FREQ_600 */ + 0x1, /* MV_DDR_FREQ_300 */ + 0x2, /* MV_DDR_FREQ_900 */ + 0x1, /* MV_DDR_FREQ_360 */ + 0x2 /* MV_DDR_FREQ_1000 */ }; static u16 a38x_vco_freq_per_sar_ref_clk_25_mhz[] = { @@ -177,10 +174,11 @@ static u32 dq_bit_map_2_phy_pin[] = { void mv_ddr_mem_scrubbing(void) { + ddr3_new_tip_ecc_scrub(); } static int ddr3_tip_a38x_set_divider(u8 dev_num, u32 if_id, - enum hws_ddr_freq freq); + enum mv_ddr_freq freq); /* * Read temperature TJ value @@ -219,7 +217,7 @@ static u32 ddr3_ctrl_get_junc_temp(u8 dev_num) * 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, +static int ddr3_tip_a38x_get_freq_config(u8 dev_num, enum mv_ddr_freq freq, struct hws_tip_freq_config_info *freq_config_info) { @@ -377,13 +375,13 @@ static int ddr3_tip_a38x_select_ddr_controller(u8 dev_num, int enable) static u8 ddr3_tip_clock_mode(u32 frequency) { - if ((frequency == DDR_FREQ_LOW_FREQ) || (freq_val[frequency] <= 400)) + if ((frequency == MV_DDR_FREQ_LOW_FREQ) || (mv_ddr_freq_get(frequency) <= 400)) return 1; return 2; } -static int mv_ddr_sar_freq_get(int dev_num, enum hws_ddr_freq *freq) +static int mv_ddr_sar_freq_get(int dev_num, enum mv_ddr_freq *freq) { u32 reg, ref_clk_satr; @@ -402,7 +400,7 @@ static int mv_ddr_sar_freq_get(int dev_num, enum hws_ddr_freq *freq) reg)); /* fallthrough */ case 0x0: - *freq = DDR_FREQ_333; + *freq = MV_DDR_FREQ_333; break; case 0x3: DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR, @@ -410,7 +408,7 @@ static int mv_ddr_sar_freq_get(int dev_num, enum hws_ddr_freq *freq) reg)); /* fallthrough */ case 0x2: - *freq = DDR_FREQ_400; + *freq = MV_DDR_FREQ_400; break; case 0xd: DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR, @@ -418,10 +416,10 @@ static int mv_ddr_sar_freq_get(int dev_num, enum hws_ddr_freq *freq) reg)); /* fallthrough */ case 0x4: - *freq = DDR_FREQ_533; + *freq = MV_DDR_FREQ_533; break; case 0x6: - *freq = DDR_FREQ_600; + *freq = MV_DDR_FREQ_600; break; case 0x11: case 0x14: @@ -430,7 +428,7 @@ static int mv_ddr_sar_freq_get(int dev_num, enum hws_ddr_freq *freq) reg)); /* fallthrough */ case 0x8: - *freq = DDR_FREQ_667; + *freq = MV_DDR_FREQ_667; break; case 0x15: case 0x1b: @@ -439,16 +437,16 @@ static int mv_ddr_sar_freq_get(int dev_num, enum hws_ddr_freq *freq) reg)); /* fallthrough */ case 0xc: - *freq = DDR_FREQ_800; + *freq = MV_DDR_FREQ_800; break; case 0x10: - *freq = DDR_FREQ_933; + *freq = MV_DDR_FREQ_933; break; case 0x12: - *freq = DDR_FREQ_900; + *freq = MV_DDR_FREQ_900; break; case 0x13: - *freq = DDR_FREQ_933; + *freq = MV_DDR_FREQ_933; break; default: *freq = 0; @@ -457,16 +455,16 @@ static int mv_ddr_sar_freq_get(int dev_num, enum hws_ddr_freq *freq) } else { /* REFCLK 40MHz case */ switch (reg) { case 0x3: - *freq = DDR_FREQ_400; + *freq = MV_DDR_FREQ_400; break; case 0x5: - *freq = DDR_FREQ_533; + *freq = MV_DDR_FREQ_533; break; case 0xb: - *freq = DDR_FREQ_800; + *freq = MV_DDR_FREQ_800; break; case 0x1e: - *freq = DDR_FREQ_900; + *freq = MV_DDR_FREQ_900; break; default: *freq = 0; @@ -477,7 +475,7 @@ static int mv_ddr_sar_freq_get(int dev_num, enum hws_ddr_freq *freq) return MV_OK; } -static int ddr3_tip_a38x_get_medium_freq(int dev_num, enum hws_ddr_freq *freq) +static int ddr3_tip_a38x_get_medium_freq(int dev_num, enum mv_ddr_freq *freq) { u32 reg, ref_clk_satr; @@ -493,37 +491,37 @@ static int ddr3_tip_a38x_get_medium_freq(int dev_num, enum hws_ddr_freq *freq) case 0x0: case 0x1: /* Medium is same as TF to run PBS in this freq */ - *freq = DDR_FREQ_333; + *freq = MV_DDR_FREQ_333; break; case 0x2: case 0x3: /* Medium is same as TF to run PBS in this freq */ - *freq = DDR_FREQ_400; + *freq = MV_DDR_FREQ_400; break; case 0x4: case 0xd: /* Medium is same as TF to run PBS in this freq */ - *freq = DDR_FREQ_533; + *freq = MV_DDR_FREQ_533; break; case 0x8: case 0x10: case 0x11: case 0x14: - *freq = DDR_FREQ_333; + *freq = MV_DDR_FREQ_333; break; case 0xc: case 0x15: case 0x1b: - *freq = DDR_FREQ_400; + *freq = MV_DDR_FREQ_400; break; case 0x6: - *freq = DDR_FREQ_300; + *freq = MV_DDR_FREQ_300; break; case 0x12: - *freq = DDR_FREQ_360; + *freq = MV_DDR_FREQ_360; break; case 0x13: - *freq = DDR_FREQ_400; + *freq = MV_DDR_FREQ_400; break; default: *freq = 0; @@ -533,17 +531,17 @@ static int ddr3_tip_a38x_get_medium_freq(int dev_num, enum hws_ddr_freq *freq) switch (reg) { case 0x3: /* Medium is same as TF to run PBS in this freq */ - *freq = DDR_FREQ_400; + *freq = MV_DDR_FREQ_400; break; case 0x5: /* Medium is same as TF to run PBS in this freq */ - *freq = DDR_FREQ_533; + *freq = MV_DDR_FREQ_533; break; case 0xb: - *freq = DDR_FREQ_400; + *freq = MV_DDR_FREQ_400; break; case 0x1e: - *freq = DDR_FREQ_360; + *freq = MV_DDR_FREQ_360; break; default: *freq = 0; @@ -682,7 +680,7 @@ static int mv_ddr_sw_db_init(u32 dev_num, u32 board_id) 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; + enum mv_ddr_freq ddr_freq = tm->interface_params[0].memory_freq; mask_tune_func = (SET_LOW_FREQ_MASK_BIT | LOAD_PATTERN_MASK_BIT | @@ -699,7 +697,7 @@ static int mv_ddr_training_mask_set(void) CENTRALIZATION_TX_MASK_BIT); rl_mid_freq_wa = 1; - if ((ddr_freq == DDR_FREQ_333) || (ddr_freq == DDR_FREQ_400)) { + if ((ddr_freq == MV_DDR_FREQ_333) || (ddr_freq == MV_DDR_FREQ_400)) { mask_tune_func = (WRITE_LEVELING_MASK_BIT | LOAD_PATTERN_2_MASK_BIT | WRITE_LEVELING_SUPP_MASK_BIT | @@ -712,7 +710,7 @@ static int mv_ddr_training_mask_set(void) } /* Supplementary not supported for ECC modes */ - if (1 == ddr3_if_ecc_enabled()) { + if (mv_ddr_is_ecc_ena()) { mask_tune_func &= ~WRITE_LEVELING_SUPP_TF_MASK_BIT; mask_tune_func &= ~WRITE_LEVELING_SUPP_MASK_BIT; mask_tune_func &= ~PBS_TX_MASK_BIT; @@ -734,11 +732,12 @@ void mv_ddr_set_calib_controller(void) } static int ddr3_tip_a38x_set_divider(u8 dev_num, u32 if_id, - enum hws_ddr_freq frequency) + enum mv_ddr_freq frequency) { u32 divider = 0; u32 sar_val, ref_clk_satr; u32 async_val; + u32 freq = mv_ddr_freq_get(frequency); if (if_id != 0) { DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR, @@ -755,11 +754,11 @@ static int ddr3_tip_a38x_set_divider(u8 dev_num, u32 if_id, 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]; + divider = a38x_vco_freq_per_sar_ref_clk_25_mhz[sar_val] / freq; else - divider = a38x_vco_freq_per_sar_ref_clk_40_mhz[sar_val] / freq_val[frequency]; + divider = a38x_vco_freq_per_sar_ref_clk_40_mhz[sar_val] / freq; - if ((async_mode_at_tf == 1) && (freq_val[frequency] > 400)) { + if ((async_mode_at_tf == 1) && (freq > 400)) { /* Set async mode */ dunit_write(0x20220, 0x1000, 0x1000); dunit_write(0xe42f4, 0x200, 0x200); @@ -769,42 +768,38 @@ static int ddr3_tip_a38x_set_divider(u8 dev_num, u32 if_id, /* Set KNL values */ switch (frequency) { -#ifdef CONFIG_DDR3 - case DDR_FREQ_467: + case MV_DDR_FREQ_467: async_val = 0x806f012; break; - case DDR_FREQ_533: + case MV_DDR_FREQ_533: async_val = 0x807f012; break; - case DDR_FREQ_600: + case MV_DDR_FREQ_600: async_val = 0x805f00a; break; -#endif - case DDR_FREQ_667: + case MV_DDR_FREQ_667: async_val = 0x809f012; break; - case DDR_FREQ_800: + case MV_DDR_FREQ_800: async_val = 0x807f00a; break; -#ifdef CONFIG_DDR3 - case DDR_FREQ_850: + case MV_DDR_FREQ_850: async_val = 0x80cb012; break; -#endif - case DDR_FREQ_900: + case MV_DDR_FREQ_900: async_val = 0x80d7012; break; - case DDR_FREQ_933: + case MV_DDR_FREQ_933: async_val = 0x80df012; break; - case DDR_FREQ_1000: + case MV_DDR_FREQ_1000: async_val = 0x80ef012; break; - case DDR_FREQ_1066: + case MV_DDR_FREQ_1066: async_val = 0x80ff012; break; default: - /* set DDR_FREQ_667 as default */ + /* set MV_DDR_FREQ_667 as default */ async_val = 0x809f012; } dunit_write(0xe42f0, 0xffffffff, async_val); @@ -890,7 +885,7 @@ int mv_ddr_early_init(void) mv_ddr_sw_db_init(0, 0); - if (tm->interface_params[0].memory_freq != DDR_FREQ_SAR) + if (tm->interface_params[0].memory_freq != MV_DDR_FREQ_SAR) async_mode_at_tf = 1; return MV_OK; @@ -934,7 +929,7 @@ int ddr3_silicon_post_init(void) u32 mv_ddr_init_freq_get(void) { - enum hws_ddr_freq freq; + enum mv_ddr_freq freq; mv_ddr_sar_freq_get(0, &freq); diff --git a/drivers/ddr/marvell/a38x/mv_ddr_plat.h b/drivers/ddr/marvell/a38x/mv_ddr_plat.h index 9c5fdecd93..a307b67976 100644 --- a/drivers/ddr/marvell/a38x/mv_ddr_plat.h +++ b/drivers/ddr/marvell/a38x/mv_ddr_plat.h @@ -1,11 +1,7 @@ -/* 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_DEVICE_NUM 1 #define MAX_INTERFACE_NUM 1 #define MAX_BUS_NUM 5 #define DDR_IF_CTRL_SUBPHYS_NUM 3 @@ -121,6 +117,9 @@ #define DLB_QUEUE_MAP_REG 0x1784 #define DLB_SPLIT_REG 0x1788 +/* ck swap control subphy number */ +#define CK_SWAP_CTRL_PHY_NUM 2 + /* Subphy result control per byte registers */ #define RESULT_CONTROL_BYTE_PUP_0_REG 0x1830 #define RESULT_CONTROL_BYTE_PUP_1_REG 0x1834 @@ -221,7 +220,7 @@ 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); - +u32 mv_ddr_init_freq_get(void); void mv_ddr_odpg_enable(void); void mv_ddr_odpg_disable(void); void mv_ddr_odpg_done_clr(void); @@ -233,4 +232,5 @@ 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/mv_ddr_regs.h b/drivers/ddr/marvell/a38x/mv_ddr_regs.h index ceda204a49..cf2a6c92e8 100644 --- a/drivers/ddr/marvell/a38x/mv_ddr_regs.h +++ b/drivers/ddr/marvell/a38x/mv_ddr_regs.h @@ -134,6 +134,7 @@ #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 +#define SDRAM_OP_CMD_ALL_CS_MASK 0xf enum { CMD_NORMAL, CMD_PRECHARGE, @@ -270,6 +271,10 @@ enum { #define ZQC_CFG_REG 0x15e4 #define DRAM_PHY_CFG_REG 0x15ec #define ODPG_CTRL_CTRL_REG 0x1600 +#define ODPG_CTRL_AUTO_REFRESH_OFFS 21 +#define ODPG_CTRL_AUTO_REFRESH_MASK 0x1 +#define ODPG_CTRL_AUTO_REFRESH_DIS 1 +#define ODPG_CTRL_AUTO_REFRESH_ENA 0 #define ODPG_DATA_CTRL_REG 0x1630 #define ODPG_WRBUF_WR_CTRL_OFFS 0 @@ -406,6 +411,20 @@ enum { #define CRX_PHY_REG(cs) (CRX_PHY_BASE + (cs) * 0x4) #define PHY_CTRL_PHY_REG 0x90 +#define INV_PAD0_OFFS 2 +#define INV_PAD1_OFFS 3 +#define INV_PAD2_OFFS 4 +#define INV_PAD3_OFFS 5 +#define INV_PAD4_OFFS 6 +#define INV_PAD5_OFFS 7 +#define INV_PAD6_OFFS 8 +#define INV_PAD7_OFFS 9 +#define INV_PAD8_OFFS 10 +#define INV_PAD9_OFFS 11 +#define INV_PAD10_OFFS 12 +#define INV_PAD_MASK 0x1 +#define INVERT_PAD 1 + #define ADLL_CFG0_PHY_REG 0x92 #define ADLL_CFG1_PHY_REG 0x93 #define ADLL_CFG2_PHY_REG 0x94 diff --git a/drivers/ddr/marvell/a38x/mv_ddr_spd.c b/drivers/ddr/marvell/a38x/mv_ddr_spd.c index e9e7f18098..04dbfe94d6 100644 --- a/drivers/ddr/marvell/a38x/mv_ddr_spd.c +++ b/drivers/ddr/marvell/a38x/mv_ddr_spd.c @@ -81,9 +81,6 @@ int mv_ddr_spd_timing_calc(union mv_ddr_spd_data *spd_data, unsigned int timing_ 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 + @@ -127,6 +124,13 @@ int mv_ddr_spd_timing_calc(union mv_ddr_spd_data *spd_data, unsigned int timing_ return 1; timing_data[MV_DDR_TRRD_L_MIN] = calc_val; + /* t ccd l min, ps */ + calc_val = spd_data->byte_fields.byte_40 * MV_DDR_SPD_DATA_MTB + + (signed char)spd_data->byte_fields.byte_117 * MV_DDR_SPD_DATA_FTB; + if (calc_val < 0) + return 1; + timing_data[MV_DDR_TCCD_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)) * @@ -136,17 +140,11 @@ int mv_ddr_spd_timing_calc(union mv_ddr_spd_data *spd_data, unsigned int timing_ 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; } diff --git a/drivers/ddr/marvell/a38x/mv_ddr_topology.c b/drivers/ddr/marvell/a38x/mv_ddr_topology.c index f56ce06770..ef3b658a78 100644 --- a/drivers/ddr/marvell/a38x/mv_ddr_topology.c +++ b/drivers/ddr/marvell/a38x/mv_ddr_topology.c @@ -2,15 +2,16 @@ /* * Copyright (C) Marvell International Ltd. and its affiliates */ +#include "ddr_ml_wrapper.h" +#include "mv_ddr_plat.h" #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" - +#include "mv_ddr_training_db.h" unsigned int mv_ddr_cl_calc(unsigned int taa_min, unsigned int tclk) { @@ -32,54 +33,57 @@ unsigned int mv_ddr_cwl_calc(unsigned int tclk) cwl = 11; else if (tclk >= 833) cwl = 12; + else if (tclk >= 750) + cwl = 14; + else if (tclk >= 625) + cwl = 16; else cwl = 0; return cwl; } -struct mv_ddr_topology_map *mv_ddr_topology_map_update(void) +int mv_ddr_topology_map_update(void) { struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + struct if_params *iface_params = &(tm->interface_params[0]); 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; + enum mv_ddr_speed_bin speed_bin_index; + enum mv_ddr_freq freq = MV_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 (iface_params->memory_freq == MV_DDR_FREQ_SAR) + iface_params->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; + return -1; } /* 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; + return -1; } /* update device width in topology map */ - tm->interface_params[0].bus_width = mv_ddr_spd_dev_width_get(&tm->spd_data); + iface_params->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); + iface_params->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; - } + for (i = 0; i < octets_per_if_num; i++) + iface_params->as_bus_params[i].cs_bitmask = val; /* check dram module type */ val = mv_ddr_spd_module_type_get(&tm->spd_data); @@ -93,48 +97,44 @@ struct mv_ddr_topology_map *mv_ddr_topology_map_update(void) break; default: printf("mv_ddr: unsupported dram module type found\n"); - return NULL; + return -1; } /* 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; - } + for (i = 0; i < octets_per_if_num; i++) + iface_params->as_bus_params[i].mirror_enable_bitmask = val << 1; - tclk = 1000000 / freq_val[tm->interface_params[0].memory_freq]; + tclk = 1000000 / mv_ddr_freq_get(iface_params->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; + return -1; } - tm->interface_params[0].cas_wl = val; + iface_params->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; + return -1; } - tm->interface_params[0].cas_l = val; + iface_params->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; + speed_bin_index = iface_params->speed_bin_index; + freq = iface_params->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 (iface_params->cas_l == 0) + iface_params->cas_l = mv_ddr_cl_val_get(speed_bin_index, 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]; + if (iface_params->cas_wl == 0) + iface_params->cas_wl = mv_ddr_cwl_val_get(speed_bin_index, freq); } - - return tm; + return 0; } unsigned short mv_ddr_bus_bit_mask_get(void) @@ -195,3 +195,150 @@ unsigned int mv_ddr_if_bus_width_get(void) return bus_width; } + +unsigned int mv_ddr_cs_num_get(void) +{ + unsigned int cs_num = 0; + unsigned int cs, sphy; + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + struct if_params *iface_params = &(tm->interface_params[0]); + unsigned int sphy_max = ddr3_tip_dev_attr_get(0, MV_ATTR_OCTET_PER_INTERFACE); + + for (sphy = 0; sphy < sphy_max; sphy++) { + VALIDATE_BUS_ACTIVE(tm->bus_act_mask, sphy); + break; + } + + for (cs = 0; cs < MAX_CS_NUM; cs++) { + VALIDATE_ACTIVE(iface_params->as_bus_params[sphy].cs_bitmask, cs); + cs_num++; + } + + return cs_num; +} + +int mv_ddr_is_ecc_ena(void) +{ + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + + 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; +} + +/* translate topology map definition to real memory size in bits */ +static unsigned int mem_size[] = { + ADDR_SIZE_512MB, + ADDR_SIZE_1GB, + ADDR_SIZE_2GB, + ADDR_SIZE_4GB, + ADDR_SIZE_8GB + /* TODO: add capacity up to 256GB */ +}; + +unsigned long long mv_ddr_mem_sz_per_cs_get(void) +{ + unsigned long long mem_sz_per_cs; + unsigned int i, sphys, sphys_per_dunit; + unsigned int sphy_max = ddr3_tip_dev_attr_get(0, MV_ATTR_OCTET_PER_INTERFACE); + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + struct if_params *iface_params = &(tm->interface_params[0]); + + /* calc number of active subphys excl. ecc one */ + for (i = 0, sphys = 0; i < sphy_max - 1; i++) { + VALIDATE_BUS_ACTIVE(tm->bus_act_mask, i); + sphys++; + } + + /* calc number of subphys per ddr unit */ + if (iface_params->bus_width == MV_DDR_DEV_WIDTH_8BIT) + sphys_per_dunit = MV_DDR_ONE_SPHY_PER_DUNIT; + else if (iface_params->bus_width == MV_DDR_DEV_WIDTH_16BIT) + sphys_per_dunit = MV_DDR_TWO_SPHY_PER_DUNIT; + else { + printf("mv_ddr: unsupported bus width type found\n"); + return 0; + } + + /* calc dram size per cs */ + mem_sz_per_cs = (unsigned long long)mem_size[iface_params->memory_size] * + (unsigned long long)sphys / + (unsigned long long)sphys_per_dunit; + + return mem_sz_per_cs; +} + +unsigned long long mv_ddr_mem_sz_get(void) +{ + unsigned long long tot_mem_sz = 0; + unsigned long long mem_sz_per_cs = 0; + unsigned long long max_cs = mv_ddr_cs_num_get(); + + mem_sz_per_cs = mv_ddr_mem_sz_per_cs_get(); + tot_mem_sz = max_cs * mem_sz_per_cs; + + return tot_mem_sz; +} + +unsigned int mv_ddr_rtt_nom_get(void) +{ + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + unsigned int rtt_nom = tm->edata.mem_edata.rtt_nom; + + if (rtt_nom >= MV_DDR_RTT_NOM_PARK_RZQ_LAST) { + printf("error: %s: unsupported rtt_nom parameter found\n", __func__); + rtt_nom = PARAM_UNDEFINED; + } + + return rtt_nom; +} + +unsigned int mv_ddr_rtt_park_get(void) +{ + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + unsigned int cs_num = mv_ddr_cs_num_get(); + unsigned int rtt_park = MV_DDR_RTT_NOM_PARK_RZQ_LAST; + + if (cs_num > 0 && cs_num <= MAX_CS_NUM) + rtt_park = tm->edata.mem_edata.rtt_park[cs_num - 1]; + + if (rtt_park >= MV_DDR_RTT_NOM_PARK_RZQ_LAST) { + printf("error: %s: unsupported rtt_park parameter found\n", __func__); + rtt_park = PARAM_UNDEFINED; + } + + return rtt_park; +} + +unsigned int mv_ddr_rtt_wr_get(void) +{ + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + unsigned int cs_num = mv_ddr_cs_num_get(); + unsigned int rtt_wr = MV_DDR_RTT_WR_RZQ_LAST; + + if (cs_num > 0 && cs_num <= MAX_CS_NUM) + rtt_wr = tm->edata.mem_edata.rtt_wr[cs_num - 1]; + + if (rtt_wr >= MV_DDR_RTT_WR_RZQ_LAST) { + printf("error: %s: unsupported rtt_wr parameter found\n", __func__); + rtt_wr = PARAM_UNDEFINED; + } + + return rtt_wr; +} + +unsigned int mv_ddr_dic_get(void) +{ + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + unsigned int dic = tm->edata.mem_edata.dic; + + if (dic >= MV_DDR_DIC_RZQ_LAST) { + printf("error: %s: unsupported dic parameter found\n", __func__); + dic = PARAM_UNDEFINED; + } + + return dic; +} diff --git a/drivers/ddr/marvell/a38x/mv_ddr_topology.h b/drivers/ddr/marvell/a38x/mv_ddr_topology.h index 7bef2d1e0e..766f25db57 100644 --- a/drivers/ddr/marvell/a38x/mv_ddr_topology.h +++ b/drivers/ddr/marvell/a38x/mv_ddr_topology.h @@ -6,6 +6,75 @@ #ifndef _MV_DDR_TOPOLOGY_H #define _MV_DDR_TOPOLOGY_H +#define MAX_CS_NUM 4 + +enum mv_ddr_speed_bin { + SPEED_BIN_DDR_800D, + SPEED_BIN_DDR_800E, + SPEED_BIN_DDR_1066E, + SPEED_BIN_DDR_1066F, + SPEED_BIN_DDR_1066G, + SPEED_BIN_DDR_1333F, + SPEED_BIN_DDR_1333G, + SPEED_BIN_DDR_1333H, + SPEED_BIN_DDR_1333J, + SPEED_BIN_DDR_1600G, + SPEED_BIN_DDR_1600H, + SPEED_BIN_DDR_1600J, + SPEED_BIN_DDR_1600K, + SPEED_BIN_DDR_1866J, + SPEED_BIN_DDR_1866K, + SPEED_BIN_DDR_1866L, + SPEED_BIN_DDR_1866M, + SPEED_BIN_DDR_2133K, + SPEED_BIN_DDR_2133L, + SPEED_BIN_DDR_2133M, + SPEED_BIN_DDR_2133N, + + SPEED_BIN_DDR_1333H_EXT, + SPEED_BIN_DDR_1600K_EXT, + SPEED_BIN_DDR_1866M_EXT +}; + +enum mv_ddr_freq { + MV_DDR_FREQ_LOW_FREQ, + MV_DDR_FREQ_400, + MV_DDR_FREQ_533, + MV_DDR_FREQ_667, + MV_DDR_FREQ_800, + MV_DDR_FREQ_933, + MV_DDR_FREQ_1066, + MV_DDR_FREQ_311, + MV_DDR_FREQ_333, + MV_DDR_FREQ_467, + MV_DDR_FREQ_850, + MV_DDR_FREQ_600, + MV_DDR_FREQ_300, + MV_DDR_FREQ_900, + MV_DDR_FREQ_360, + MV_DDR_FREQ_1000, + MV_DDR_FREQ_LAST, + MV_DDR_FREQ_SAR +}; + +enum mv_ddr_speed_bin_timing { + SPEED_BIN_TRCD, + SPEED_BIN_TRP, + SPEED_BIN_TRAS, + SPEED_BIN_TRC, + SPEED_BIN_TRRD1K, + SPEED_BIN_TRRD2K, + SPEED_BIN_TPD, + SPEED_BIN_TFAW1K, + SPEED_BIN_TFAW2K, + SPEED_BIN_TWTR, + SPEED_BIN_TRTP, + SPEED_BIN_TWR, + SPEED_BIN_TMOD, + SPEED_BIN_TXPDLL, + SPEED_BIN_TXSDLL +}; + /* ddr bus masks */ #define BUS_MASK_32BIT 0xf #define BUS_MASK_32BIT_ECC 0x1f @@ -16,6 +85,12 @@ #define MV_DDR_64BIT_ECC_PUP8_BUS_MASK 0x1ff #define MV_DDR_32BIT_ECC_PUP8_BUS_MASK 0x10f +#define MV_DDR_CS_BITMASK_1CS 0x1 +#define MV_DDR_CS_BITMASK_2CS 0x3 + +#define MV_DDR_ONE_SPHY_PER_DUNIT 1 +#define MV_DDR_TWO_SPHY_PER_DUNIT 2 + /* source of ddr configuration data */ enum mv_ddr_cfg_src { MV_DDR_CFG_DEFAULT, /* based on data in mv_ddr_topology_map structure */ @@ -25,11 +100,6 @@ enum mv_ddr_cfg_src { 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, @@ -53,12 +123,78 @@ enum mv_ddr_timing_data { 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_TCCD_L_MIN, /* min cas to cas delay time (t ccd_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_electrical_data { + MV_DDR_CK_DLY, + MV_DDR_PHY_REG3, + MV_DDR_ZPRI_DATA, + MV_DDR_ZNRI_DATA, + MV_DDR_ZPRI_CTRL, + MV_DDR_ZNRI_CTRL, + MV_DDR_ZPODT_DATA, + MV_DDR_ZNODT_DATA, + MV_DDR_ZPODT_CTRL, + MV_DDR_ZNODT_CTRL, + MV_DDR_DIC, + MV_DDR_ODT_CFG, + MV_DDR_RTT_NOM, + MV_DDR_RTT_WR, + MV_DDR_RTT_PARK, + MV_DDR_EDATA_LAST +}; + +/* memory electrical configuration values */ +enum mv_ddr_rtt_nom_park_evalue { + MV_DDR_RTT_NOM_PARK_RZQ_DISABLE, + MV_DDR_RTT_NOM_PARK_RZQ_DIV4, /* 60-Ohm; RZQ = 240-Ohm */ + MV_DDR_RTT_NOM_PARK_RZQ_DIV2, /* 120-Ohm; RZQ = 240-Ohm */ + MV_DDR_RTT_NOM_PARK_RZQ_DIV6, /* 40-Ohm; RZQ = 240-Ohm */ + MV_DDR_RTT_NOM_PARK_RZQ_DIV1, /* 240-Ohm; RZQ = 240-Ohm */ + MV_DDR_RTT_NOM_PARK_RZQ_DIV5, /* 48-Ohm; RZQ = 240-Ohm */ + MV_DDR_RTT_NOM_PARK_RZQ_DIV3, /* 80-Ohm; RZQ = 240-Ohm */ + MV_DDR_RTT_NOM_PARK_RZQ_DIV7, /* 34-Ohm; RZQ = 240-Ohm */ + MV_DDR_RTT_NOM_PARK_RZQ_LAST +}; + +enum mv_ddr_rtt_wr_evalue { + MV_DDR_RTT_WR_DYN_ODT_OFF, + MV_DDR_RTT_WR_RZQ_DIV2, /* 120-Ohm; RZQ = 240-Ohm */ + MV_DDR_RTT_WR_RZQ_DIV1, /* 240-Ohm; RZQ = 240-Ohm */ + MV_DDR_RTT_WR_HIZ, + MV_DDR_RTT_WR_RZQ_DIV3, /* 80-Ohm; RZQ = 240-Ohm */ + MV_DDR_RTT_WR_RZQ_LAST +}; + +enum mv_ddr_dic_evalue { + MV_DDR_DIC_RZQ_DIV7, /* 34-Ohm; RZQ = 240-Ohm */ + MV_DDR_DIC_RZQ_DIV5, /* 48-Ohm; RZQ = 240-Ohm */ + MV_DDR_DIC_RZQ_LAST +}; + +/* phy electrical configuration values */ +enum mv_ddr_ohm_evalue { + MV_DDR_OHM_30 = 30, + MV_DDR_OHM_48 = 48, + MV_DDR_OHM_60 = 60, + MV_DDR_OHM_80 = 80, + MV_DDR_OHM_120 = 120, + MV_DDR_OHM_240 = 240, + MV_DDR_OHM_LAST +}; + +/* mac electrical configuration values */ +enum mv_ddr_odt_cfg_evalue { + MV_DDR_ODT_CFG_NORMAL, + MV_DDR_ODT_CFG_ALWAYS_ON, + MV_DDR_ODT_CFG_LAST +}; + enum mv_ddr_dev_width { /* sdram device width */ MV_DDR_DEV_WIDTH_4BIT, MV_DDR_DEV_WIDTH_8BIT, @@ -119,11 +255,75 @@ enum mv_ddr_die_count { MV_DDR_DIE_CNT_LAST }; +#define IS_ACTIVE(mask, id) \ + ((mask) & (1 << (id))) + +#define VALIDATE_ACTIVE(mask, id) \ + { \ + if (IS_ACTIVE(mask, id) == 0) \ + continue; \ + } + +#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) == BUS_MASK_16BIT_ECC_PUP3) ? 1 : 0) + +#define DDR3_IS_ECC_PUP4_MODE(if_mask) \ + (((if_mask) == BUS_MASK_32BIT_ECC || \ + (if_mask) == BUS_MASK_16BIT_ECC) ? 1 : 0) + +#define DDR3_IS_16BIT_DRAM_MODE(mask) \ + (((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, sphys) \ + (((sphys) == 9) && \ + (((mask) == BUS_MASK_32BIT) || \ + ((mask) == MV_DDR_32BIT_ECC_PUP8_BUS_MASK)) ? 1 : 0) + +#define MV_DDR_IS_HALF_BUS_DRAM_MODE(mask, sphys) \ + (MV_DDR_IS_32BIT_IN_64BIT_DRAM_MODE(mask, sphys) || \ + DDR3_IS_16BIT_DRAM_MODE(mask)) + +struct mv_ddr_topology_map *mv_ddr_topology_map_get(void); 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); +int mv_ddr_topology_map_update(void); unsigned short mv_ddr_bus_bit_mask_get(void); unsigned int mv_ddr_if_bus_width_get(void); +unsigned int mv_ddr_cs_num_get(void); +int mv_ddr_is_ecc_ena(void); +unsigned long long mv_ddr_mem_sz_per_cs_get(void); +unsigned long long mv_ddr_mem_sz_get(void); +unsigned int mv_ddr_rtt_nom_get(void); +unsigned int mv_ddr_rtt_park_get(void); +unsigned int mv_ddr_rtt_wr_get(void); +unsigned int mv_ddr_dic_get(void); #endif /* _MV_DDR_TOPOLOGY_H */ diff --git a/drivers/ddr/marvell/a38x/mv_ddr_training_db.h b/drivers/ddr/marvell/a38x/mv_ddr_training_db.h new file mode 100644 index 0000000000..838be4574d --- /dev/null +++ b/drivers/ddr/marvell/a38x/mv_ddr_training_db.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2018 Marvell International Ltd. + */ + +#ifndef _MV_DDR_TRAINING_DB_H +#define _MV_DDR_TRAINING_DB_H + +#include "mv_ddr_topology.h" + +/* in ns */ +#define TREFI_LOW 7800 +#define TREFI_HIGH 3900 + +enum mv_ddr_page_size { + MV_DDR_PAGE_SIZE_1K = 1, + MV_DDR_PAGE_SIZE_2K +}; + +struct mv_ddr_page_element { + /* 8-bit bus width page size */ + enum mv_ddr_page_size page_size_8bit; + /* 16-bit bus width page size */ + enum mv_ddr_page_size page_size_16bit; +}; + +/* cas latency value per frequency */ +struct mv_ddr_cl_val_per_freq { + unsigned int cl_val[MV_DDR_FREQ_LAST]; +}; + +u32 mv_ddr_rfc_get(u32 mem); +unsigned int *mv_ddr_freq_tbl_get(void); +u32 mv_ddr_freq_get(enum mv_ddr_freq freq); +u32 mv_ddr_page_size_get(enum mv_ddr_dev_width bus_width, enum mv_ddr_die_capacity mem_size); +unsigned int mv_ddr_speed_bin_timing_get(enum mv_ddr_speed_bin index, enum mv_ddr_speed_bin_timing element); +u32 mv_ddr_cl_val_get(u32 index, u32 freq); +u32 mv_ddr_cwl_val_get(u32 index, u32 freq); + +#endif /* _MV_DDR_TRAINING_DB_H */ diff --git a/drivers/ddr/marvell/a38x/xor.c b/drivers/ddr/marvell/a38x/xor.c index f859596d89..5fb9e216d3 100644 --- a/drivers/ddr/marvell/a38x/xor.c +++ b/drivers/ddr/marvell/a38x/xor.c @@ -4,6 +4,7 @@ */ #include "ddr3_init.h" +#include "mv_ddr_common.h" #include "xor_regs.h" /* defines */ @@ -339,16 +340,17 @@ 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("DDR Training Sequence - Start scrubbing\n"); - max_cs = ddr3_tip_max_cs_get(dev_num); + max_cs = mv_ddr_cs_num_get(); for (cs_c = 0; cs_c < max_cs; cs_c++) cs_ena |= 1 << cs_c; - /* assume that all CS have same size */ +#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X) + /* all chip-selects are of same size */ ddr3_calc_mem_cs_size(0, &cs_mem_size); +#endif mv_sys_xor_init(max_cs, cs_ena, cs_mem_size, 0); total_mem_size = max_cs * cs_mem_size; -- 2.25.1