diff options
Diffstat (limited to 'drivers/ddr/marvell/a38x/ddr3_init.c')
-rw-r--r-- | drivers/ddr/marvell/a38x/ddr3_init.c | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/drivers/ddr/marvell/a38x/ddr3_init.c b/drivers/ddr/marvell/a38x/ddr3_init.c new file mode 100644 index 00000000000..27eb3ac1735 --- /dev/null +++ b/drivers/ddr/marvell/a38x/ddr3_init.c @@ -0,0 +1,173 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) Marvell International Ltd. and its affiliates + */ + +#include "ddr3_init.h" +#include "mv_ddr_common.h" + +#if defined(CONFIG_DDR4) +static char *ddr_type = "DDR4"; +#else /* CONFIG_DDR4 */ +static char *ddr_type = "DDR3"; +#endif /* CONFIG_DDR4 */ + +/* + * generic_init_controller controls D-unit configuration: + * '1' - dynamic D-unit configuration, + */ +u8 generic_init_controller = 1; + +static int mv_ddr_training_params_set(u8 dev_num); + +/* + * Name: ddr3_init - Main DDR3 Init function + * Desc: This routine initialize the DDR3 MC and runs HW training. + * Args: None. + * Notes: + * Returns: None. + */ +int ddr3_init(void) +{ + int status; + int is_manual_cal_done; + + /* Print mv_ddr version */ + mv_ddr_ver_print(); + + mv_ddr_pre_training_fixup(); + + /* SoC/Board special initializations */ + mv_ddr_pre_training_soc_config(ddr_type); + + /* Set log level for training library */ + mv_ddr_user_log_level_set(DEBUG_BLOCK_ALL); + + mv_ddr_early_init(); + + if (mv_ddr_topology_map_update()) { + printf("mv_ddr: failed to update topology\n"); + return MV_FAIL; + } + + if (mv_ddr_early_init2() != MV_OK) + return MV_FAIL; + + /* Set training algorithm's parameters */ + status = mv_ddr_training_params_set(0); + if (MV_OK != status) + return status; + + mv_ddr_mc_config(); + + is_manual_cal_done = mv_ddr_manual_cal_do(); + + mv_ddr_mc_init(); + + if (!is_manual_cal_done) { +#if defined(CONFIG_DDR4) + status = mv_ddr4_calibration_adjust(0, 1, 0); + if (status != MV_OK) { + printf("%s: failed (0x%x)\n", __func__, status); + return status; + } +#endif + } + + + status = ddr3_silicon_post_init(); + if (MV_OK != status) { + printf("DDR3 Post Init - FAILED 0x%x\n", status); + return status; + } + + /* PHY initialization (Training) */ + status = hws_ddr3_tip_run_alg(0, ALGO_TYPE_DYNAMIC); + if (MV_OK != status) { + printf("%s Training Sequence - FAILED\n", ddr_type); + return status; + } + + + /* Post MC/PHY initializations */ + mv_ddr_post_training_soc_config(ddr_type); + + mv_ddr_post_training_fixup(); + + if (mv_ddr_is_ecc_ena()) + mv_ddr_mem_scrubbing(); + + printf("mv_ddr: completed successfully\n"); + + return MV_OK; +} + +/* + * Name: mv_ddr_training_params_set + * Desc: + * Args: + * Notes: sets internal training params + * Returns: + */ +static int mv_ddr_training_params_set(u8 dev_num) +{ + struct tune_train_params params; + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + int status; + u32 cs_num; + int ck_delay; + + cs_num = mv_ddr_cs_num_get(); + ck_delay = mv_ddr_ck_delay_get(); + + /* NOTE: do not remove any field initilization */ + params.ck_delay = TUNE_TRAINING_PARAMS_CK_DELAY; + params.phy_reg3_val = TUNE_TRAINING_PARAMS_PHYREG3VAL; + params.g_zpri_data = TUNE_TRAINING_PARAMS_PRI_DATA; + params.g_znri_data = TUNE_TRAINING_PARAMS_NRI_DATA; + params.g_zpri_ctrl = TUNE_TRAINING_PARAMS_PRI_CTRL; + params.g_znri_ctrl = TUNE_TRAINING_PARAMS_NRI_CTRL; + params.g_znodt_data = TUNE_TRAINING_PARAMS_N_ODT_DATA; + params.g_zpodt_ctrl = TUNE_TRAINING_PARAMS_P_ODT_CTRL; + params.g_znodt_ctrl = TUNE_TRAINING_PARAMS_N_ODT_CTRL; + +#if defined(CONFIG_DDR4) + params.g_zpodt_data = TUNE_TRAINING_PARAMS_P_ODT_DATA_DDR4; + params.g_odt_config = TUNE_TRAINING_PARAMS_ODT_CONFIG_DDR4; + params.g_rtt_nom = TUNE_TRAINING_PARAMS_RTT_NOM_DDR4; + params.g_dic = TUNE_TRAINING_PARAMS_DIC_DDR4; + if (cs_num == 1) { + params.g_rtt_wr = TUNE_TRAINING_PARAMS_RTT_WR_1CS; + params.g_rtt_park = TUNE_TRAINING_PARAMS_RTT_PARK_1CS; + } else { + params.g_rtt_wr = TUNE_TRAINING_PARAMS_RTT_WR_2CS; + params.g_rtt_park = TUNE_TRAINING_PARAMS_RTT_PARK_2CS; + } +#else /* CONFIG_DDR4 */ + params.g_zpodt_data = TUNE_TRAINING_PARAMS_P_ODT_DATA; + params.g_dic = TUNE_TRAINING_PARAMS_DIC; + params.g_rtt_nom = TUNE_TRAINING_PARAMS_RTT_NOM; + if (cs_num == 1) { + params.g_rtt_wr = TUNE_TRAINING_PARAMS_RTT_WR_1CS; + params.g_odt_config = TUNE_TRAINING_PARAMS_ODT_CONFIG_1CS; + } else { + params.g_rtt_wr = TUNE_TRAINING_PARAMS_RTT_WR_2CS; + params.g_odt_config = TUNE_TRAINING_PARAMS_ODT_CONFIG_2CS; + } +#endif /* CONFIG_DDR4 */ + + if (ck_delay > 0) + params.ck_delay = ck_delay; + + /* Use platform specific override ODT value */ + if (tm->odt_config) + params.g_odt_config = tm->odt_config; + + status = ddr3_tip_tune_training_params(dev_num, ¶ms); + if (MV_OK != status) { + printf("%s Training Sequence - FAILED\n", ddr_type); + return status; + } + + return MV_OK; +} |