1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) Marvell International Ltd. and its affiliates 4 */ 5 6 #include "mv_ddr_spd.h" 7 8 #define MV_DDR_SPD_DATA_MTB 125 /* medium timebase, ps */ 9 #define MV_DDR_SPD_DATA_FTB 1 /* fine timebase, ps */ 10 #define MV_DDR_SPD_MSB_OFFS 8 /* most significant byte offset, bits */ 11 12 #define MV_DDR_SPD_SUPPORTED_CLS_NUM 30 13 14 static unsigned int mv_ddr_spd_supported_cls[MV_DDR_SPD_SUPPORTED_CLS_NUM]; 15 16 int mv_ddr_spd_supported_cls_calc(union mv_ddr_spd_data *spd_data) 17 { 18 unsigned int byte, bit, start_cl; 19 20 start_cl = (spd_data->all_bytes[23] & 0x8) ? 23 : 7; 21 22 for (byte = 20; byte < 23; byte++) { 23 for (bit = 0; bit < 8; bit++) { 24 if (spd_data->all_bytes[byte] & (1 << bit)) 25 mv_ddr_spd_supported_cls[(byte - 20) * 8 + bit] = start_cl + (byte - 20) * 8 + bit; 26 else 27 mv_ddr_spd_supported_cls[(byte - 20) * 8 + bit] = 0; 28 } 29 } 30 31 for (byte = 23, bit = 0; bit < 6; bit++) { 32 if (spd_data->all_bytes[byte] & (1 << bit)) 33 mv_ddr_spd_supported_cls[(byte - 20) * 8 + bit] = start_cl + (byte - 20) * 8 + bit; 34 else 35 mv_ddr_spd_supported_cls[(byte - 20) * 8 + bit] = 0; 36 } 37 38 return 0; 39 } 40 41 unsigned int mv_ddr_spd_supported_cl_get(unsigned int cl) 42 { 43 unsigned int supported_cl; 44 int i = 0; 45 46 while (i < MV_DDR_SPD_SUPPORTED_CLS_NUM && 47 mv_ddr_spd_supported_cls[i] < cl) 48 i++; 49 50 if (i < MV_DDR_SPD_SUPPORTED_CLS_NUM) 51 supported_cl = mv_ddr_spd_supported_cls[i]; 52 else 53 supported_cl = 0; 54 55 return supported_cl; 56 } 57 58 int mv_ddr_spd_timing_calc(union mv_ddr_spd_data *spd_data, unsigned int timing_data[]) 59 { 60 int calc_val; 61 62 /* t ck avg min, ps */ 63 calc_val = spd_data->byte_fields.byte_18 * MV_DDR_SPD_DATA_MTB + 64 (signed char)spd_data->byte_fields.byte_125 * MV_DDR_SPD_DATA_FTB; 65 if (calc_val < 0) 66 return 1; 67 timing_data[MV_DDR_TCK_AVG_MIN] = calc_val; 68 69 /* t aa min, ps */ 70 calc_val = spd_data->byte_fields.byte_24 * MV_DDR_SPD_DATA_MTB + 71 (signed char)spd_data->byte_fields.byte_123 * MV_DDR_SPD_DATA_FTB; 72 if (calc_val < 0) 73 return 1; 74 timing_data[MV_DDR_TAA_MIN] = calc_val; 75 76 /* t rfc1 min, ps */ 77 timing_data[MV_DDR_TRFC1_MIN] = (spd_data->byte_fields.byte_30 + 78 (spd_data->byte_fields.byte_31 << MV_DDR_SPD_MSB_OFFS)) * MV_DDR_SPD_DATA_MTB; 79 80 /* t wr min, ps */ 81 timing_data[MV_DDR_TWR_MIN] = (spd_data->byte_fields.byte_42 + 82 (spd_data->byte_fields.byte_41.bit_fields.t_wr_min_msn << MV_DDR_SPD_MSB_OFFS)) * 83 MV_DDR_SPD_DATA_MTB; 84 /* FIXME: wa: set twr to a default value, if it's unset on spd */ 85 if (timing_data[MV_DDR_TWR_MIN] == 0) 86 timing_data[MV_DDR_TWR_MIN] = 15000; 87 88 /* t rcd min, ps */ 89 calc_val = spd_data->byte_fields.byte_25 * MV_DDR_SPD_DATA_MTB + 90 (signed char)spd_data->byte_fields.byte_122 * MV_DDR_SPD_DATA_FTB; 91 if (calc_val < 0) 92 return 1; 93 timing_data[MV_DDR_TRCD_MIN] = calc_val; 94 95 /* t rp min, ps */ 96 calc_val = spd_data->byte_fields.byte_26 * MV_DDR_SPD_DATA_MTB + 97 (signed char)spd_data->byte_fields.byte_121 * MV_DDR_SPD_DATA_FTB; 98 if (calc_val < 0) 99 return 1; 100 timing_data[MV_DDR_TRP_MIN] = calc_val; 101 102 /* t rc min, ps */ 103 calc_val = (spd_data->byte_fields.byte_29 + 104 (spd_data->byte_fields.byte_27.bit_fields.t_rc_min_msn << MV_DDR_SPD_MSB_OFFS)) * 105 MV_DDR_SPD_DATA_MTB + 106 (signed char)spd_data->byte_fields.byte_120 * MV_DDR_SPD_DATA_FTB; 107 if (calc_val < 0) 108 return 1; 109 timing_data[MV_DDR_TRC_MIN] = calc_val; 110 111 /* t ras min, ps */ 112 timing_data[MV_DDR_TRAS_MIN] = (spd_data->byte_fields.byte_28 + 113 (spd_data->byte_fields.byte_27.bit_fields.t_ras_min_msn << MV_DDR_SPD_MSB_OFFS)) * 114 MV_DDR_SPD_DATA_MTB; 115 116 /* t rrd s min, ps */ 117 calc_val = spd_data->byte_fields.byte_38 * MV_DDR_SPD_DATA_MTB + 118 (signed char)spd_data->byte_fields.byte_119 * MV_DDR_SPD_DATA_FTB; 119 if (calc_val < 0) 120 return 1; 121 timing_data[MV_DDR_TRRD_S_MIN] = calc_val; 122 123 /* t rrd l min, ps */ 124 calc_val = spd_data->byte_fields.byte_39 * MV_DDR_SPD_DATA_MTB + 125 (signed char)spd_data->byte_fields.byte_118 * MV_DDR_SPD_DATA_FTB; 126 if (calc_val < 0) 127 return 1; 128 timing_data[MV_DDR_TRRD_L_MIN] = calc_val; 129 130 /* t faw min, ps */ 131 timing_data[MV_DDR_TFAW_MIN] = (spd_data->byte_fields.byte_37 + 132 (spd_data->byte_fields.byte_36.bit_fields.t_faw_min_msn << MV_DDR_SPD_MSB_OFFS)) * 133 MV_DDR_SPD_DATA_MTB; 134 135 /* t wtr s min, ps */ 136 timing_data[MV_DDR_TWTR_S_MIN] = (spd_data->byte_fields.byte_44 + 137 (spd_data->byte_fields.byte_43.bit_fields.t_wtr_s_min_msn << MV_DDR_SPD_MSB_OFFS)) * 138 MV_DDR_SPD_DATA_MTB; 139 /* FIXME: wa: set twtr_s to a default value, if it's unset on spd */ 140 if (timing_data[MV_DDR_TWTR_S_MIN] == 0) 141 timing_data[MV_DDR_TWTR_S_MIN] = 2500; 142 143 /* t wtr l min, ps */ 144 timing_data[MV_DDR_TWTR_L_MIN] = (spd_data->byte_fields.byte_45 + 145 (spd_data->byte_fields.byte_43.bit_fields.t_wtr_l_min_msn << MV_DDR_SPD_MSB_OFFS)) * 146 MV_DDR_SPD_DATA_MTB; 147 /* FIXME: wa: set twtr_l to a default value, if it's unset on spd */ 148 if (timing_data[MV_DDR_TWTR_L_MIN] == 0) 149 timing_data[MV_DDR_TWTR_L_MIN] = 7500; 150 151 return 0; 152 } 153 154 enum mv_ddr_dev_width mv_ddr_spd_dev_width_get(union mv_ddr_spd_data *spd_data) 155 { 156 unsigned char dev_width = spd_data->byte_fields.byte_12.bit_fields.device_width; 157 enum mv_ddr_dev_width ret_val; 158 159 switch (dev_width) { 160 case 0x00: 161 ret_val = MV_DDR_DEV_WIDTH_4BIT; 162 break; 163 case 0x01: 164 ret_val = MV_DDR_DEV_WIDTH_8BIT; 165 break; 166 case 0x02: 167 ret_val = MV_DDR_DEV_WIDTH_16BIT; 168 break; 169 case 0x03: 170 ret_val = MV_DDR_DEV_WIDTH_32BIT; 171 break; 172 default: 173 ret_val = MV_DDR_DEV_WIDTH_LAST; 174 } 175 176 return ret_val; 177 } 178 179 enum mv_ddr_die_capacity mv_ddr_spd_die_capacity_get(union mv_ddr_spd_data *spd_data) 180 { 181 unsigned char die_cap = spd_data->byte_fields.byte_4.bit_fields.die_capacity; 182 enum mv_ddr_die_capacity ret_val; 183 184 switch (die_cap) { 185 case 0x00: 186 ret_val = MV_DDR_DIE_CAP_256MBIT; 187 break; 188 case 0x01: 189 ret_val = MV_DDR_DIE_CAP_512MBIT; 190 break; 191 case 0x02: 192 ret_val = MV_DDR_DIE_CAP_1GBIT; 193 break; 194 case 0x03: 195 ret_val = MV_DDR_DIE_CAP_2GBIT; 196 break; 197 case 0x04: 198 ret_val = MV_DDR_DIE_CAP_4GBIT; 199 break; 200 case 0x05: 201 ret_val = MV_DDR_DIE_CAP_8GBIT; 202 break; 203 case 0x06: 204 ret_val = MV_DDR_DIE_CAP_16GBIT; 205 break; 206 case 0x07: 207 ret_val = MV_DDR_DIE_CAP_32GBIT; 208 break; 209 case 0x08: 210 ret_val = MV_DDR_DIE_CAP_12GBIT; 211 break; 212 case 0x09: 213 ret_val = MV_DDR_DIE_CAP_24GBIT; 214 break; 215 default: 216 ret_val = MV_DDR_DIE_CAP_LAST; 217 } 218 219 return ret_val; 220 } 221 222 unsigned char mv_ddr_spd_mem_mirror_get(union mv_ddr_spd_data *spd_data) 223 { 224 unsigned char mem_mirror = spd_data->byte_fields.byte_131.bit_fields.rank_1_mapping; 225 226 return mem_mirror; 227 } 228 229 enum mv_ddr_pkg_rank mv_ddr_spd_pri_bus_width_get(union mv_ddr_spd_data *spd_data) 230 { 231 unsigned char pri_bus_width = spd_data->byte_fields.byte_13.bit_fields.primary_bus_width; 232 enum mv_ddr_pri_bus_width ret_val; 233 234 switch (pri_bus_width) { 235 case 0x00: 236 ret_val = MV_DDR_PRI_BUS_WIDTH_8; 237 break; 238 case 0x01: 239 ret_val = MV_DDR_PRI_BUS_WIDTH_16; 240 break; 241 case 0x02: 242 ret_val = MV_DDR_PRI_BUS_WIDTH_32; 243 break; 244 case 0x03: 245 ret_val = MV_DDR_PRI_BUS_WIDTH_64; 246 break; 247 default: 248 ret_val = MV_DDR_PRI_BUS_WIDTH_LAST; 249 } 250 251 return ret_val; 252 } 253 254 enum mv_ddr_pkg_rank mv_ddr_spd_bus_width_ext_get(union mv_ddr_spd_data *spd_data) 255 { 256 unsigned char bus_width_ext = spd_data->byte_fields.byte_13.bit_fields.bus_width_ext; 257 enum mv_ddr_bus_width_ext ret_val; 258 259 switch (bus_width_ext) { 260 case 0x00: 261 ret_val = MV_DDR_BUS_WIDTH_EXT_0; 262 break; 263 case 0x01: 264 ret_val = MV_DDR_BUS_WIDTH_EXT_8; 265 break; 266 default: 267 ret_val = MV_DDR_BUS_WIDTH_EXT_LAST; 268 } 269 270 return ret_val; 271 } 272 273 static enum mv_ddr_pkg_rank mv_ddr_spd_pkg_rank_get(union mv_ddr_spd_data *spd_data) 274 { 275 unsigned char pkg_rank = spd_data->byte_fields.byte_12.bit_fields.dimm_pkg_ranks_num; 276 enum mv_ddr_pkg_rank ret_val; 277 278 switch (pkg_rank) { 279 case 0x00: 280 ret_val = MV_DDR_PKG_RANK_1; 281 break; 282 case 0x01: 283 ret_val = MV_DDR_PKG_RANK_2; 284 break; 285 case 0x02: 286 ret_val = MV_DDR_PKG_RANK_3; 287 break; 288 case 0x03: 289 ret_val = MV_DDR_PKG_RANK_4; 290 break; 291 case 0x04: 292 ret_val = MV_DDR_PKG_RANK_5; 293 break; 294 case 0x05: 295 ret_val = MV_DDR_PKG_RANK_6; 296 break; 297 case 0x06: 298 ret_val = MV_DDR_PKG_RANK_7; 299 break; 300 case 0x07: 301 ret_val = MV_DDR_PKG_RANK_8; 302 break; 303 default: 304 ret_val = MV_DDR_PKG_RANK_LAST; 305 } 306 307 return ret_val; 308 } 309 310 static enum mv_ddr_die_count mv_ddr_spd_die_count_get(union mv_ddr_spd_data *spd_data) 311 { 312 unsigned char die_count = spd_data->byte_fields.byte_6.bit_fields.die_count; 313 enum mv_ddr_die_count ret_val; 314 315 switch (die_count) { 316 case 0x00: 317 ret_val = MV_DDR_DIE_CNT_1; 318 break; 319 case 0x01: 320 ret_val = MV_DDR_DIE_CNT_2; 321 break; 322 case 0x02: 323 ret_val = MV_DDR_DIE_CNT_3; 324 break; 325 case 0x03: 326 ret_val = MV_DDR_DIE_CNT_4; 327 break; 328 case 0x04: 329 ret_val = MV_DDR_DIE_CNT_5; 330 break; 331 case 0x05: 332 ret_val = MV_DDR_DIE_CNT_6; 333 break; 334 case 0x06: 335 ret_val = MV_DDR_DIE_CNT_7; 336 break; 337 case 0x07: 338 ret_val = MV_DDR_DIE_CNT_8; 339 break; 340 default: 341 ret_val = MV_DDR_DIE_CNT_LAST; 342 } 343 344 return ret_val; 345 } 346 347 unsigned char mv_ddr_spd_cs_bit_mask_get(union mv_ddr_spd_data *spd_data) 348 { 349 unsigned char cs_bit_mask = 0x0; 350 enum mv_ddr_pkg_rank pkg_rank = mv_ddr_spd_pkg_rank_get(spd_data); 351 enum mv_ddr_die_count die_cnt = mv_ddr_spd_die_count_get(spd_data); 352 353 if (pkg_rank == MV_DDR_PKG_RANK_1 && die_cnt == MV_DDR_DIE_CNT_1) 354 cs_bit_mask = 0x1; 355 else if (pkg_rank == MV_DDR_PKG_RANK_1 && die_cnt == MV_DDR_DIE_CNT_2) 356 cs_bit_mask = 0x3; 357 else if (pkg_rank == MV_DDR_PKG_RANK_2 && die_cnt == MV_DDR_DIE_CNT_1) 358 cs_bit_mask = 0x3; 359 else if (pkg_rank == MV_DDR_PKG_RANK_2 && die_cnt == MV_DDR_DIE_CNT_2) 360 cs_bit_mask = 0xf; 361 362 return cs_bit_mask; 363 } 364 365 unsigned char mv_ddr_spd_dev_type_get(union mv_ddr_spd_data *spd_data) 366 { 367 unsigned char dev_type = spd_data->byte_fields.byte_2; 368 369 return dev_type; 370 } 371 372 unsigned char mv_ddr_spd_module_type_get(union mv_ddr_spd_data *spd_data) 373 { 374 unsigned char module_type = spd_data->byte_fields.byte_3.bit_fields.module_type; 375 376 return module_type; 377 } 378