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