diff --git a/drivers/ddr/marvell/a38x/ddr3_init.h b/drivers/ddr/marvell/a38x/ddr3_init.h index 8cb08864c2..a4c75a9fa6 100644 --- a/drivers/ddr/marvell/a38x/ddr3_init.h +++ b/drivers/ddr/marvell/a38x/ddr3_init.h @@ -183,7 +183,8 @@ extern u32 g_znodt_data; extern u32 g_zpodt_ctrl; extern u32 g_znodt_ctrl; extern u32 g_dic; -extern u32 g_odt_config; +extern u32 g_odt_config_2cs; +extern u32 g_odt_config_1cs; extern u32 g_rtt_nom; extern u8 debug_training_access; diff --git a/drivers/ddr/marvell/a38x/ddr3_topology_def.h b/drivers/ddr/marvell/a38x/ddr3_topology_def.h index 64a0447dd1..a17eca0418 100644 --- a/drivers/ddr/marvell/a38x/ddr3_topology_def.h +++ b/drivers/ddr/marvell/a38x/ddr3_topology_def.h @@ -70,7 +70,8 @@ enum speed_bin_table_elements { SPEED_BIN_TWTR, SPEED_BIN_TRTP, SPEED_BIN_TWR, - SPEED_BIN_TMOD + SPEED_BIN_TMOD, + SPEED_BIN_TXPDLL }; #endif /* _DDR3_TOPOLOGY_DEF_H */ diff --git a/drivers/ddr/marvell/a38x/ddr3_training.c b/drivers/ddr/marvell/a38x/ddr3_training.c index e70ca4b425..ef471e565e 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training.c +++ b/drivers/ddr/marvell/a38x/ddr3_training.c @@ -22,6 +22,8 @@ #define GET_CS_FROM_MASK(mask) (cs_mask2_num[mask]) #define CS_CBE_VALUE(cs_num) (cs_cbe_reg[cs_num]) +#define TIMES_9_TREFI_CYCLES 0x8 + u32 window_mem_addr = 0; u32 phy_reg0_val = 0; u32 phy_reg1_val = 8; @@ -315,6 +317,7 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_ enum hws_access_type access_type = ACCESS_TYPE_UNICAST; u32 data_read[MAX_INTERFACE_NUM]; struct hws_topology_map *tm = ddr3_get_topology_map(); + u32 odt_config = g_odt_config_2cs; DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE, ("Init_controller, do_mrs_phy=%d, is_ctrl64_bit=%d\n", @@ -507,7 +510,9 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_ DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE, ("cl_value 0x%x cwl_val 0x%x\n", cl_value, cwl_val)); - + t_wr = TIME_2_CLOCK_CYCLES(speed_bin_table(speed_bin_index, + SPEED_BIN_TWR), + t_ckclk); data_value = ((cl_mask_table[cl_value] & 0x1) << 2) | ((cl_mask_table[cl_value] & 0xe) << 3); @@ -517,8 +522,9 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_ (0x7 << 4) | (1 << 2))); CHECK_STATUS(ddr3_tip_if_write (dev_num, access_type, if_id, - MR0_REG, twr_mask_table[t_wr + 1], - 0xe00)); + MR0_REG, twr_mask_table[t_wr + 1] << 9, + (0x7 << 9))); + /* * MR1: Set RTT and DIC Design GL values @@ -570,6 +576,9 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_ DUNIT_CONTROL_HIGH_REG, (init_cntr_prm->msys_init << 7), (1 << 7))); + /* calculate number of CS (per interface) */ + CHECK_STATUS(calc_cs_num + (dev_num, if_id, &cs_num)); timing = tm->interface_params[if_id].timing; if (mode2_t != 0xff) { @@ -578,9 +587,6 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_ /* Board topology map is forcing timing */ t2t = (timing == HWS_TIM_2T) ? 1 : 0; } else { - /* calculate number of CS (per interface) */ - CHECK_STATUS(calc_cs_num - (dev_num, if_id, &cs_num)); t2t = (cs_num == 1) ? 0 : 1; } @@ -589,16 +595,15 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_ DDR_CONTROL_LOW_REG, t2t << 3, 0x3 << 3)); /* move the block to ddr3_tip_set_timing - start */ - t_pd = GET_MAX_VALUE(t_ckclk * 3, - speed_bin_table(speed_bin_index, - SPEED_BIN_TPD)); - t_pd = TIME_2_CLOCK_CYCLES(t_pd, t_ckclk); - txpdll = GET_MAX_VALUE(t_ckclk * 10, 24); + t_pd = TIMES_9_TREFI_CYCLES; + txpdll = GET_MAX_VALUE(t_ckclk * 10, + speed_bin_table(speed_bin_index, + SPEED_BIN_TXPDLL)); txpdll = CEIL_DIVIDE((txpdll - 1), t_ckclk); CHECK_STATUS(ddr3_tip_if_write (dev_num, access_type, if_id, - DDR_TIMING_REG, txpdll << 4, - 0x1f << 4)); + DDR_TIMING_REG, txpdll << 4 | t_pd, + 0x1f << 4 | 0xf)); CHECK_STATUS(ddr3_tip_if_write (dev_num, access_type, if_id, DDR_TIMING_REG, 0x28 << 9, 0x3f << 9)); @@ -623,9 +628,11 @@ int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_ (1 << 11))); /* Set Active control for ODT write transactions */ + if (cs_num == 1) + odt_config = g_odt_config_1cs; CHECK_STATUS(ddr3_tip_if_write (dev_num, ACCESS_TYPE_MULTICAST, - PARAM_NOT_CARE, 0x1494, g_odt_config, + PARAM_NOT_CARE, 0x1494, odt_config, MASK_ALL_BITS)); } } else { @@ -1224,6 +1231,7 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type, u32 cl_value = 0, cwl_value = 0, mem_mask = 0, val = 0, bus_cnt = 0, t_hclk = 0, t_wr = 0, refresh_interval_cnt = 0, cnt_id; + u32 t_ckclk; u32 t_refi = 0, end_if, start_if; u32 bus_index = 0; int is_dll_off = 0; @@ -1372,7 +1380,7 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type, /* adjust t_refi to new frequency */ t_refi = (tm->interface_params[if_id].interface_temp == - HWS_TEMP_HIGH) ? TREFI_LOW : TREFI_HIGH; + HWS_TEMP_HIGH) ? TREFI_HIGH : TREFI_LOW; t_refi *= 1000; /*psec */ /* HCLK in[ps] */ @@ -1390,8 +1398,12 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type, CHECK_STATUS(ddr3_tip_if_write (dev_num, access_type, if_id, DFS_REG, (cwl_mask_table[cwl_value] << 12), 0x7000)); - t_wr = speed_bin_table(speed_bin_index, SPEED_BIN_TWR); - t_wr = (t_wr / 1000); + + t_ckclk = MEGA / freq_val[frequency]; + t_wr = TIME_2_CLOCK_CYCLES(speed_bin_table(speed_bin_index, + SPEED_BIN_TWR), + t_ckclk); + CHECK_STATUS(ddr3_tip_if_write (dev_num, access_type, if_id, DFS_REG, (twr_mask_table[t_wr + 1] << 16), 0x70000)); @@ -1539,7 +1551,7 @@ int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type, CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id, ODT_TIMING_LOW, val, 0xffff0)); - val = 0x71 | ((cwl_value - 1) << 8) | ((cwl_value + 5) << 12); + val = 0x91 | ((cwl_value - 1) << 8) | ((cwl_value + 5) << 12); CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id, ODT_TIMING_HI_REG, val, 0xffff)); @@ -1591,7 +1603,7 @@ static int ddr3_tip_write_odt(u32 dev_num, enum hws_access_type access_type, CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id, ODT_TIMING_LOW, val, 0xffff0)); - val = 0x71 | ((cwl_value - 1) << 8) | ((cwl_value + 5) << 12); + val = 0x91 | ((cwl_value - 1) << 8) | ((cwl_value + 5) << 12); CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id, ODT_TIMING_HI_REG, val, 0xffff)); if (odt_additional == 1) { diff --git a/drivers/ddr/marvell/a38x/ddr3_training_db.c b/drivers/ddr/marvell/a38x/ddr3_training_db.c index 861dfb19c3..0e11b434ab 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_db.c +++ b/drivers/ddr/marvell/a38x/ddr3_training_db.c @@ -152,18 +152,18 @@ u8 twr_mask_table[] = { 10, 10, 10, - 1, /*5 */ - 2, /*6 */ - 3, /*7 */ + 1, /*5*/ + 2, /*6*/ + 3, /*7*/ + 4, /*8*/ 10, + 5, /*10*/ 10, - 5, /*10 */ + 6, /*12*/ 10, - 6, /*12 */ + 7, /*14*/ 10, - 7, /*14 */ - 10, - 0 /*16 */ + 0 /*16*/ }; u8 cl_mask_table[] = { @@ -431,6 +431,9 @@ u32 speed_bin_table(u8 index, enum speed_bin_table_elements element) case SPEED_BIN_TMOD: result = 15000; break; + case SPEED_BIN_TXPDLL: + result = 24000; + break; default: break; } diff --git a/drivers/ddr/marvell/a38x/ddr3_training_hw_algo.c b/drivers/ddr/marvell/a38x/ddr3_training_hw_algo.c index 56fce174d4..1fc173b600 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_hw_algo.c +++ b/drivers/ddr/marvell/a38x/ddr3_training_hw_algo.c @@ -17,7 +17,7 @@ #define VREF_MAX_INDEX 7 #define MAX_VALUE (1024 - 1) #define MIN_VALUE (-MAX_VALUE) -#define GET_RD_SAMPLE_DELAY(data, cs) ((data >> rd_sample_mask[cs]) & 0xf) +#define GET_RD_SAMPLE_DELAY(data, cs) ((data >> rd_sample_mask[cs]) & 0x1f) u32 ck_delay = (u32)-1, ck_delay_16 = (u32)-1; u32 ca_delay; @@ -49,7 +49,7 @@ static u32 rd_sample_mask[] = { */ int ddr3_tip_write_additional_odt_setting(u32 dev_num, u32 if_id) { - u32 cs_num = 0, max_read_sample = 0, min_read_sample = 0; + u32 cs_num = 0, max_cs = 0, max_read_sample = 0, min_read_sample = 0x1f; u32 data_read[MAX_INTERFACE_NUM] = { 0 }; u32 read_sample[MAX_CS_NUM]; u32 val; @@ -66,15 +66,19 @@ int ddr3_tip_write_additional_odt_setting(u32 dev_num, u32 if_id) data_read, MASK_ALL_BITS)); val = data_read[if_id]; - for (cs_num = 0; cs_num < MAX_CS_NUM; cs_num++) { + max_cs = hws_ddr3_tip_max_cs_get(); + + for (cs_num = 0; cs_num < max_cs; cs_num++) { read_sample[cs_num] = GET_RD_SAMPLE_DELAY(val, cs_num); /* find maximum of read_samples */ if (read_sample[cs_num] >= max_read_sample) { - if (read_sample[cs_num] == max_read_sample) - max_phase = MIN_VALUE; - else + if (read_sample[cs_num] == max_read_sample) { + /* search for max phase */; + } else { max_read_sample = read_sample[cs_num]; + max_phase = MIN_VALUE; + } for (pup_index = 0; pup_index < tm->num_of_bus_per_interface; @@ -97,10 +101,12 @@ int ddr3_tip_write_additional_odt_setting(u32 dev_num, u32 if_id) min_read_sample = read_sample[cs_num]; } + if (min_read_sample <= tm->interface_params[if_id].cas_l) { + min_read_sample = (int)tm->interface_params[if_id].cas_l; + } + min_read_sample = min_read_sample - 1; max_read_sample = max_read_sample + 4 + (max_phase + 1) / 2 + 1; - if (min_read_sample >= 0xf) - min_read_sample = 0xf; if (max_read_sample >= 0x1f) max_read_sample = 0x1f; diff --git a/drivers/ddr/marvell/a38x/ddr3_training_static.c b/drivers/ddr/marvell/a38x/ddr3_training_static.c index 5101f3f383..b73bbf4f1b 100644 --- a/drivers/ddr/marvell/a38x/ddr3_training_static.c +++ b/drivers/ddr/marvell/a38x/ddr3_training_static.c @@ -21,7 +21,8 @@ u32 g_zpodt_data = 45; /* controller data - P ODT */ u32 g_znodt_data = 45; /* controller data - N ODT */ u32 g_zpodt_ctrl = 45; /* controller data - P ODT */ u32 g_znodt_ctrl = 45; /* controller data - N ODT */ -u32 g_odt_config = 0x120012; +u32 g_odt_config_2cs = 0x120012; +u32 g_odt_config_1cs = 0x10000; u32 g_rtt_nom = 0x44; u32 g_dic = 0x2;