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 <judge.packham@gmail.com>
Reviewed-by: Stefan Roese <sr@denx.de>
Tested-by: Baruch Siach <baruch@tkos.co.il>
Signed-off-by: Stefan Roese <sr@denx.de>
This commit is contained in:
Chris Packham 2018-12-03 14:26:49 +13:00 committed by Stefan Roese
parent 3589025867
commit ebb1a59325
37 changed files with 1163 additions and 1261 deletions

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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();

View File

@ -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;

View File

@ -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 */

View File

@ -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 */

View File

@ -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;
}

View File

@ -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;

View File

@ -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++) {

View File

@ -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;
}

View File

@ -4,6 +4,7 @@
*/
#include "ddr3_init.h"
#include "mv_ddr_regs.h"
#define VREF_INITIAL_STEP 3
#define VREF_SECOND_STEP 1

View File

@ -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_ */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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_ */

View File

@ -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);

View File

@ -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,
&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,

View File

@ -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_ */

View File

@ -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);

View File

@ -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;

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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";

View File

@ -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);

View File

@ -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);

View File

@ -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 */

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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;