northbridge/amd/amdfam10: Set DIMM voltage based on SPD data
Change-Id: I67a76cf0e4ebc33fbd7dd151bb68dce1fc6ba680 Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> Reviewed-on: http://review.coreboot.org/11957 Tested-by: build bot (Jenkins) Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
This commit is contained in:
parent
65eec4d959
commit
2a83935d9f
|
@ -83,6 +83,10 @@ config DIMM_REGISTERED
|
||||||
bool
|
bool
|
||||||
default n
|
default n
|
||||||
|
|
||||||
|
config DIMM_VOLTAGE_SET_SUPPORT
|
||||||
|
bool
|
||||||
|
default n
|
||||||
|
|
||||||
if DIMM_FBDIMM
|
if DIMM_FBDIMM
|
||||||
config DIMM_SUPPORT
|
config DIMM_SUPPORT
|
||||||
hex
|
hex
|
||||||
|
|
|
@ -303,8 +303,7 @@ void northbridge_acpi_write_vars(device_t device)
|
||||||
} else {
|
} else {
|
||||||
if((sysconf.pci1234[0] >> 12) & 0xff) { //sb chain on other than bus 0
|
if((sysconf.pci1234[0] >> 12) & 0xff) { //sb chain on other than bus 0
|
||||||
CBST = (u8) (0x0f);
|
CBST = (u8) (0x0f);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
CBST = (u8) (0x00);
|
CBST = (u8) (0x00);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1063,6 +1063,36 @@ static int amdfam10_get_smbios_data17(int* count, int handle, int parent_handle,
|
||||||
snprintf(string_buffer, sizeof (string_buffer), "%08X", mem_info->dct_stat[node].DimmSerialNumber[slot]);
|
snprintf(string_buffer, sizeof (string_buffer), "%08X", mem_info->dct_stat[node].DimmSerialNumber[slot]);
|
||||||
t->serial_number = smbios_add_string(t->eos, string_buffer);
|
t->serial_number = smbios_add_string(t->eos, string_buffer);
|
||||||
}
|
}
|
||||||
|
if (IS_ENABLED(CONFIG_DIMM_DDR2)) {
|
||||||
|
/* JEDEC specifies 1.8V only, so assume that the memory is configured for 1.8V */
|
||||||
|
t->minimum_voltage = 1800;
|
||||||
|
t->maximum_voltage = 1800;
|
||||||
|
t->configured_voltage = 1800;
|
||||||
|
} else if (IS_ENABLED(CONFIG_DIMM_DDR3)) {
|
||||||
|
#if IS_ENABLED(CONFIG_DIMM_DDR3)
|
||||||
|
/* Find the maximum and minimum supported voltages */
|
||||||
|
uint8_t supported_voltages = mem_info->dct_stat[node].DimmSupportedVoltages[slot];
|
||||||
|
if (supported_voltages & 0x8)
|
||||||
|
t->minimum_voltage = 1150;
|
||||||
|
else if (supported_voltages & 0x4)
|
||||||
|
t->minimum_voltage = 1250;
|
||||||
|
else if (supported_voltages & 0x2)
|
||||||
|
t->minimum_voltage = 1350;
|
||||||
|
else if (supported_voltages & 0x1)
|
||||||
|
t->minimum_voltage = 1500;
|
||||||
|
|
||||||
|
if (supported_voltages & 0x1)
|
||||||
|
t->maximum_voltage = 1500;
|
||||||
|
else if (supported_voltages & 0x2)
|
||||||
|
t->maximum_voltage = 1350;
|
||||||
|
else if (supported_voltages & 0x4)
|
||||||
|
t->maximum_voltage = 1250;
|
||||||
|
else if (supported_voltages & 0x8)
|
||||||
|
t->maximum_voltage = 1150;
|
||||||
|
|
||||||
|
t->configured_voltage = mem_info->dct_stat[node].DimmConfiguredVoltage[slot];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
t->memory_error_information_handle = 0xFFFE; /* no error information handle available */
|
t->memory_error_information_handle = 0xFFFE; /* no error information handle available */
|
||||||
single_len = t->length + smbios_string_table_len(t->eos);
|
single_len = t->length + smbios_string_table_len(t->eos);
|
||||||
len += single_len;
|
len += single_len;
|
||||||
|
|
|
@ -336,6 +336,11 @@ restartinit:
|
||||||
goto fatalexit;
|
goto fatalexit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if IS_ENABLED(DIMM_VOLTAGE_SET_SUPPORT)
|
||||||
|
printk(BIOS_DEBUG, "mctAutoInitMCT_D: DIMMSetVoltage\n");
|
||||||
|
DIMMSetVoltages(pMCTstat, pDCTstatA); /* Set the DIMM voltages (mainboard specific) */
|
||||||
|
#endif
|
||||||
|
|
||||||
printk(BIOS_DEBUG, "mctAutoInitMCT_D: SyncDCTsReady_D\n");
|
printk(BIOS_DEBUG, "mctAutoInitMCT_D: SyncDCTsReady_D\n");
|
||||||
SyncDCTsReady_D(pMCTstat, pDCTstatA); /* Make sure DCTs are ready for accesses.*/
|
SyncDCTsReady_D(pMCTstat, pDCTstatA); /* Make sure DCTs are ready for accesses.*/
|
||||||
|
|
||||||
|
@ -2128,6 +2133,9 @@ static u8 DIMMPresence_D(struct MCTStatStruc *pMCTstat,
|
||||||
pDCTstat->DimmBanks[i] = 1ULL << (((mctRead_SPD(smbaddr, SPD_Density) & 0x70) >> 4) + 3);
|
pDCTstat->DimmBanks[i] = 1ULL << (((mctRead_SPD(smbaddr, SPD_Density) & 0x70) >> 4) + 3);
|
||||||
pDCTstat->DimmWidth[i] = 1ULL << ((mctRead_SPD(smbaddr, SPD_BusWidth) & 0x7) + 3);
|
pDCTstat->DimmWidth[i] = 1ULL << ((mctRead_SPD(smbaddr, SPD_BusWidth) & 0x7) + 3);
|
||||||
}
|
}
|
||||||
|
/* Check supported voltage(s) */
|
||||||
|
pDCTstat->DimmSupportedVoltages[i] = mctRead_SPD(smbaddr, SPD_Voltage) & 0x7;
|
||||||
|
pDCTstat->DimmSupportedVoltages[i] ^= 0x1; /* Invert LSB to convert from SPD format to internal bitmap format */
|
||||||
/* Check module type */
|
/* Check module type */
|
||||||
byte = mctRead_SPD(smbaddr, SPD_DIMMTYPE) & 0x7;
|
byte = mctRead_SPD(smbaddr, SPD_DIMMTYPE) & 0x7;
|
||||||
if (byte == JED_RDIMM || byte == JED_MiniRDIMM) {
|
if (byte == JED_RDIMM || byte == JED_MiniRDIMM) {
|
||||||
|
|
|
@ -202,6 +202,7 @@
|
||||||
#define JED_MiniRDIMM 0x5 /* Mini-RDIMM */
|
#define JED_MiniRDIMM 0x5 /* Mini-RDIMM */
|
||||||
#define SPD_Density 4 /* Bank address bits,SDRAM capacity */
|
#define SPD_Density 4 /* Bank address bits,SDRAM capacity */
|
||||||
#define SPD_Addressing 5 /* Row/Column address bits */
|
#define SPD_Addressing 5 /* Row/Column address bits */
|
||||||
|
#define SPD_Voltage 6 /* Supported voltage bitfield */
|
||||||
#define SPD_Organization 7 /* rank#,Device width */
|
#define SPD_Organization 7 /* rank#,Device width */
|
||||||
#define SPD_BusWidth 8 /* ECC, Bus width */
|
#define SPD_BusWidth 8 /* ECC, Bus width */
|
||||||
#define JED_ECC 8 /* ECC capability */
|
#define JED_ECC 8 /* ECC capability */
|
||||||
|
@ -581,6 +582,10 @@ struct DCTStatStruc { /* A per Node structure*/
|
||||||
struct _sDCTStruct s_C_DCTPtr[2];
|
struct _sDCTStruct s_C_DCTPtr[2];
|
||||||
/* struct _sDCTStruct s_C_DCT1Ptr[8]; */
|
/* struct _sDCTStruct s_C_DCT1Ptr[8]; */
|
||||||
|
|
||||||
|
/* DIMM supported voltage bitmap ([2:0]: 1.25V, 1.35V, 1.5V) */
|
||||||
|
uint8_t DimmSupportedVoltages[MAX_DIMMS_SUPPORTED];
|
||||||
|
uint32_t DimmConfiguredVoltage[MAX_DIMMS_SUPPORTED]; /* mV */
|
||||||
|
|
||||||
uint8_t DimmRows[MAX_DIMMS_SUPPORTED];
|
uint8_t DimmRows[MAX_DIMMS_SUPPORTED];
|
||||||
uint8_t DimmCols[MAX_DIMMS_SUPPORTED];
|
uint8_t DimmCols[MAX_DIMMS_SUPPORTED];
|
||||||
uint8_t DimmRanks[MAX_DIMMS_SUPPORTED];
|
uint8_t DimmRanks[MAX_DIMMS_SUPPORTED];
|
||||||
|
@ -901,6 +906,7 @@ u32 procOdtWorkaround(struct DCTStatStruc *pDCTstat, u32 dct, u32 val);
|
||||||
void mct_BeforeDramInit_D(struct DCTStatStruc *pDCTstat, u32 dct);
|
void mct_BeforeDramInit_D(struct DCTStatStruc *pDCTstat, u32 dct);
|
||||||
void mctGet_DIMMAddr(struct DCTStatStruc *pDCTstat, u32 node);
|
void mctGet_DIMMAddr(struct DCTStatStruc *pDCTstat, u32 node);
|
||||||
void mctSMBhub_Init(u32 node);
|
void mctSMBhub_Init(u32 node);
|
||||||
|
void DIMMSetVoltages(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA);
|
||||||
int mctRead_SPD(u32 smaddr, u32 reg);
|
int mctRead_SPD(u32 smaddr, u32 reg);
|
||||||
void InterleaveNodes_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA);
|
void InterleaveNodes_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA);
|
||||||
void InterleaveChannels_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA);
|
void InterleaveChannels_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA);
|
||||||
|
|
Loading…
Reference in New Issue