device/dram/ddr3: Fill in voltage fields for SMBIOS type 17

Parse the supported voltages from the DDR3 SPD and populate the
corresponding fields in CBMEM_ID_MEMINFO to make sure the SMBIOS
type 17 tables report the actual supported voltages of the DIMM.

Change-Id: I35af7c23f285af10b607a80eab7f4d9df664b3fd
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/90395
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
This commit is contained in:
Patrick Rudolph 2025-12-05 13:46:47 +01:00 committed by Matt DeVillier
commit 25c4501223
3 changed files with 21 additions and 1 deletions

View file

@ -173,20 +173,29 @@ int spd_decode_ddr3(struct dimm_attr_ddr3_st *dimm, spd_ddr3_raw_data spd)
/* Module nominal voltage */
reg8 = spd[6];
dimm->min_voltage = UINT16_MAX;
dimm->max_voltage = 0;
printram(" Supported voltages :");
if (reg8 & (1 << 2)) {
dimm->flags.operable_1_25V = 1;
dimm->voltage = 1250;
dimm->max_voltage = MAX(dimm->voltage, dimm->max_voltage);
dimm->min_voltage = MIN(dimm->min_voltage, dimm->voltage);
printram(" 1.25V");
}
if (reg8 & (1 << 1)) {
dimm->flags.operable_1_35V = 1;
dimm->voltage = 1300;
dimm->max_voltage = MAX(dimm->voltage, dimm->max_voltage);
dimm->min_voltage = MIN(dimm->min_voltage, dimm->voltage);
printram(" 1.35V");
}
if (!(reg8 & (1 << 0))) {
dimm->flags.operable_1_50V = 1;
dimm->voltage = 1500;
dimm->max_voltage = MAX(dimm->voltage, dimm->max_voltage);
dimm->min_voltage = MIN(dimm->min_voltage, dimm->voltage);
printram(" 1.5V");
}
printram("\n");
@ -454,6 +463,8 @@ int spd_xmp_decode_ddr3(struct dimm_attr_ddr3_st *dimm, spd_ddr3_raw_data spd,
dimm->voltage = (xmp[0] & 1) * 50;
dimm->voltage += ((xmp[0] >> 1) & 0xf) * 100;
dimm->voltage += ((xmp[0] >> 5) & 0x3) * 1000;
dimm->max_voltage = MAX(dimm->voltage, dimm->max_voltage);
dimm->min_voltage = MIN(dimm->min_voltage, dimm->voltage);
printram(" Requested voltage : %u mV\n", dimm->voltage);
@ -535,6 +546,9 @@ enum cb_err spd_add_smbios17(const u8 channel, const u8 slot, const u16 selected
dimm->channel_num = channel;
dimm->rank_per_dimm = info->ranks;
dimm->dimm_num = slot;
dimm->vdd_voltage = info->voltage;
dimm->vdd_min_voltage = info->min_voltage;
dimm->vdd_max_voltage = info->max_voltage;
memcpy(dimm->module_part_number, info->part_number, 16);
dimm->mod_id = info->manufacturer_id;
dimm->mod_type = info->dimm_type;
@ -579,6 +593,8 @@ void dram_print_spd_ddr3(const struct dimm_attr_ddr3_st *dimm)
printk(BIOS_INFO, " Column addr bits : %u\n", dimm->col_bits);
printk(BIOS_INFO, " Number of ranks : %u\n", dimm->ranks);
printk(BIOS_INFO, " DIMM Capacity : %u MB\n", dimm->size_mb);
printk(BIOS_INFO, " Vdd Min : %u mV\n", dimm->min_voltage);
printk(BIOS_INFO, " Vdd Max : %u mV\n", dimm->max_voltage);
/* CAS Latencies Supported */
val16 = dimm->cas_supported;

View file

@ -138,6 +138,10 @@ struct dimm_attr_ddr3_st {
u8 reference_card;
/* XMP: Module voltage in mV */
u16 voltage;
/* Maximum voltage the DIMM supports in mV */
u16 max_voltage;
/* Minimum voltage the DIMM supports in mV */
u16 min_voltage;
/* XMP: max DIMMs per channel supported (1-4) */
u8 dimms_per_channel;
/* Manufacturer ID */

View file

@ -305,7 +305,7 @@ void iosav_write_memory_test_sequence(ramctr_timing *ctrl, int channel, int slot
/*
* WARNING: Do not forget to increase MRC_CACHE_VERSION when the saved data is changed!
*/
#define MRC_CACHE_VERSION 5
#define MRC_CACHE_VERSION 6
enum power_down_mode {
PDM_NONE = 0,