1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) Marvell International Ltd. and its affiliates 4 */ 5 6 #include "ddr3_init.h" 7 #include "mv_ddr_common.h" 8 9 /* 10 * Translates topology map definitions to real memory size in bits 11 * (per values in ddr3_training_ip_def.h) 12 */ 13 u32 mem_size[] = { 14 ADDR_SIZE_512MB, 15 ADDR_SIZE_1GB, 16 ADDR_SIZE_2GB, 17 ADDR_SIZE_4GB, 18 ADDR_SIZE_8GB 19 }; 20 21 static char *ddr_type = "DDR3"; 22 23 /* 24 * generic_init_controller controls D-unit configuration: 25 * '1' - dynamic D-unit configuration, 26 */ 27 u8 generic_init_controller = 1; 28 29 static int mv_ddr_training_params_set(u8 dev_num); 30 31 /* 32 * Name: ddr3_init - Main DDR3 Init function 33 * Desc: This routine initialize the DDR3 MC and runs HW training. 34 * Args: None. 35 * Notes: 36 * Returns: None. 37 */ 38 int ddr3_init(void) 39 { 40 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); 41 u32 octets_per_if_num; 42 int status; 43 int is_manual_cal_done; 44 45 /* Print mv_ddr version */ 46 mv_ddr_ver_print(); 47 48 mv_ddr_pre_training_fixup(); 49 50 /* SoC/Board special initializations */ 51 mv_ddr_pre_training_soc_config(ddr_type); 52 53 /* Set log level for training library */ 54 mv_ddr_user_log_level_set(DEBUG_BLOCK_ALL); 55 56 mv_ddr_early_init(); 57 58 if (mv_ddr_topology_map_update() == NULL) { 59 printf("mv_ddr: failed to update topology\n"); 60 return MV_FAIL; 61 } 62 63 if (mv_ddr_early_init2() != MV_OK) 64 return MV_FAIL; 65 66 /* Set training algorithm's parameters */ 67 status = mv_ddr_training_params_set(0); 68 if (MV_OK != status) 69 return status; 70 71 72 mv_ddr_mc_config(); 73 74 is_manual_cal_done = mv_ddr_manual_cal_do(); 75 76 mv_ddr_mc_init(); 77 78 if (!is_manual_cal_done) { 79 } 80 81 82 status = ddr3_silicon_post_init(); 83 if (MV_OK != status) { 84 printf("DDR3 Post Init - FAILED 0x%x\n", status); 85 return status; 86 } 87 88 /* PHY initialization (Training) */ 89 status = hws_ddr3_tip_run_alg(0, ALGO_TYPE_DYNAMIC); 90 if (MV_OK != status) { 91 printf("%s Training Sequence - FAILED\n", ddr_type); 92 return status; 93 } 94 95 #if defined(CONFIG_PHY_STATIC_PRINT) 96 mv_ddr_phy_static_print(); 97 #endif 98 99 /* Post MC/PHY initializations */ 100 mv_ddr_post_training_soc_config(ddr_type); 101 102 mv_ddr_post_training_fixup(); 103 104 octets_per_if_num = ddr3_tip_dev_attr_get(0, MV_ATTR_OCTET_PER_INTERFACE); 105 if (ddr3_if_ecc_enabled()) { 106 if (MV_DDR_IS_64BIT_DRAM_MODE(tm->bus_act_mask) || 107 MV_DDR_IS_32BIT_IN_64BIT_DRAM_MODE(tm->bus_act_mask, octets_per_if_num)) 108 mv_ddr_mem_scrubbing(); 109 else 110 ddr3_new_tip_ecc_scrub(); 111 } 112 113 printf("mv_ddr: completed successfully\n"); 114 115 return MV_OK; 116 } 117 118 uint64_t mv_ddr_get_memory_size_per_cs_in_bits(void) 119 { 120 uint64_t memory_size_per_cs; 121 122 u32 bus_cnt, num_of_active_bus = 0; 123 u32 num_of_sub_phys_per_ddr_unit = 0; 124 125 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); 126 127 u32 octets_per_if_num = ddr3_tip_dev_attr_get(DEV_NUM_0, MV_ATTR_OCTET_PER_INTERFACE); 128 129 /* count the number of active bus */ 130 for (bus_cnt = 0; bus_cnt < octets_per_if_num - 1/* ignore ecc octet */; bus_cnt++) { 131 VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_cnt); 132 num_of_active_bus++; 133 } 134 135 /* calculate number of sub-phys per ddr unit */ 136 if (tm->interface_params[0].bus_width/* supports only single interface */ == MV_DDR_DEV_WIDTH_16BIT) 137 num_of_sub_phys_per_ddr_unit = TWO_SUB_PHYS; 138 if (tm->interface_params[0].bus_width/* supports only single interface */ == MV_DDR_DEV_WIDTH_8BIT) 139 num_of_sub_phys_per_ddr_unit = SINGLE_SUB_PHY; 140 141 /* calculate dram size per cs */ 142 memory_size_per_cs = (uint64_t)mem_size[tm->interface_params[0].memory_size] * (uint64_t)num_of_active_bus 143 / (uint64_t)num_of_sub_phys_per_ddr_unit * (uint64_t)MV_DDR_NUM_BITS_IN_BYTE; 144 145 return memory_size_per_cs; 146 } 147 148 uint64_t mv_ddr_get_total_memory_size_in_bits(void) 149 { 150 uint64_t total_memory_size = 0; 151 uint64_t memory_size_per_cs = 0; 152 153 /* get the number of cs */ 154 u32 max_cs = ddr3_tip_max_cs_get(DEV_NUM_0); 155 156 memory_size_per_cs = mv_ddr_get_memory_size_per_cs_in_bits(); 157 total_memory_size = (uint64_t)max_cs * memory_size_per_cs; 158 159 return total_memory_size; 160 } 161 162 int ddr3_if_ecc_enabled(void) 163 { 164 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); 165 166 if (DDR3_IS_ECC_PUP4_MODE(tm->bus_act_mask) || 167 DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask) || 168 DDR3_IS_ECC_PUP8_MODE(tm->bus_act_mask)) 169 return 1; 170 else 171 return 0; 172 } 173 174 /* 175 * Name: mv_ddr_training_params_set 176 * Desc: 177 * Args: 178 * Notes: sets internal training params 179 * Returns: 180 */ 181 static int mv_ddr_training_params_set(u8 dev_num) 182 { 183 struct tune_train_params params; 184 int status; 185 struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); 186 u32 if_id; 187 u32 cs_num; 188 189 CHECK_STATUS(ddr3_tip_get_first_active_if 190 (dev_num, tm->if_act_mask, 191 &if_id)); 192 193 CHECK_STATUS(calc_cs_num(dev_num, if_id, &cs_num)); 194 195 /* NOTE: do not remove any field initilization */ 196 params.ck_delay = TUNE_TRAINING_PARAMS_CK_DELAY; 197 params.phy_reg3_val = TUNE_TRAINING_PARAMS_PHYREG3VAL; 198 params.g_zpri_data = TUNE_TRAINING_PARAMS_PRI_DATA; 199 params.g_znri_data = TUNE_TRAINING_PARAMS_NRI_DATA; 200 params.g_zpri_ctrl = TUNE_TRAINING_PARAMS_PRI_CTRL; 201 params.g_znri_ctrl = TUNE_TRAINING_PARAMS_NRI_CTRL; 202 params.g_znodt_data = TUNE_TRAINING_PARAMS_N_ODT_DATA; 203 params.g_zpodt_ctrl = TUNE_TRAINING_PARAMS_P_ODT_CTRL; 204 params.g_znodt_ctrl = TUNE_TRAINING_PARAMS_N_ODT_CTRL; 205 206 params.g_zpodt_data = TUNE_TRAINING_PARAMS_P_ODT_DATA; 207 params.g_dic = TUNE_TRAINING_PARAMS_DIC; 208 params.g_rtt_nom = TUNE_TRAINING_PARAMS_RTT_NOM; 209 if (cs_num == 1) { 210 params.g_rtt_wr = TUNE_TRAINING_PARAMS_RTT_WR_1CS; 211 params.g_odt_config = TUNE_TRAINING_PARAMS_ODT_CONFIG_1CS; 212 } else { 213 params.g_rtt_wr = TUNE_TRAINING_PARAMS_RTT_WR_2CS; 214 params.g_odt_config = TUNE_TRAINING_PARAMS_ODT_CONFIG_2CS; 215 } 216 217 status = ddr3_tip_tune_training_params(dev_num, ¶ms); 218 if (MV_OK != status) { 219 printf("%s Training Sequence - FAILED\n", ddr_type); 220 return status; 221 } 222 223 return MV_OK; 224 } 225