diff options
Diffstat (limited to 'resources/libreboot/patch/kgpe-d16/0027-northbridge-amd-amdfam10-Set-DIMM-voltage-based-on-S.patch')
-rw-r--r-- | resources/libreboot/patch/kgpe-d16/0027-northbridge-amd-amdfam10-Set-DIMM-voltage-based-on-S.patch | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/resources/libreboot/patch/kgpe-d16/0027-northbridge-amd-amdfam10-Set-DIMM-voltage-based-on-S.patch b/resources/libreboot/patch/kgpe-d16/0027-northbridge-amd-amdfam10-Set-DIMM-voltage-based-on-S.patch new file mode 100644 index 0000000..7c45877 --- /dev/null +++ b/resources/libreboot/patch/kgpe-d16/0027-northbridge-amd-amdfam10-Set-DIMM-voltage-based-on-S.patch @@ -0,0 +1,176 @@ +From ca270728b0d2232efb4384f645d993403f4bc24e Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <kb9vqf@pearsoncomputing.net> +Date: Sat, 5 Sep 2015 18:56:05 -0500 +Subject: [PATCH 027/146] northbridge/amd/amdfam10: Set DIMM voltage based on + SPD data + +--- + src/northbridge/amd/amdfam10/acpi.c | 3 +- + src/northbridge/amd/amdfam10/northbridge.c | 73 ++++++++++++++++++++++----- + src/northbridge/amd/amdmct/mct_ddr3/mct_d.c | 6 +++ + src/northbridge/amd/amdmct/mct_ddr3/mct_d.h | 6 +++ + 4 files changed, 73 insertions(+), 15 deletions(-) + +diff --git a/src/northbridge/amd/amdfam10/acpi.c b/src/northbridge/amd/amdfam10/acpi.c +index 4b86e96..92433bb 100644 +--- a/src/northbridge/amd/amdfam10/acpi.c ++++ b/src/northbridge/amd/amdfam10/acpi.c +@@ -307,8 +307,7 @@ void northbridge_acpi_write_vars(device_t device) + } else { + if((sysconf.pci1234[0] >> 12) & 0xff) { //sb chain on other than bus 0 + CBST = (u8) (0x0f); +- } +- else { ++ } else { + CBST = (u8) (0x00); + } + } +diff --git a/src/northbridge/amd/amdfam10/northbridge.c b/src/northbridge/amd/amdfam10/northbridge.c +index 880129b..d0a0787 100644 +--- a/src/northbridge/amd/amdfam10/northbridge.c ++++ b/src/northbridge/amd/amdfam10/northbridge.c +@@ -948,19 +948,38 @@ static int amdfam10_get_smbios_data16(int* count, int handle, unsigned long *cur + + static uint16_t amdmct_mct_speed_enum_to_mhz(uint8_t speed) + { +- switch (speed) { +- case 1: +- return 200; +- case 2: +- return 266; +- case 3: +- return 333; +- case 4: +- return 400; +- case 5: +- return 533; +- default: +- return 0; ++ if (IS_ENABLED(CONFIG_DIMM_DDR2)) { ++ switch (speed) { ++ case 1: ++ return 200; ++ case 2: ++ return 266; ++ case 3: ++ return 333; ++ case 4: ++ return 400; ++ case 5: ++ return 533; ++ default: ++ return 0; ++ } ++ } else if (IS_ENABLED(CONFIG_DIMM_DDR3)) { ++ switch (speed) { ++ case 3: ++ return 333; ++ case 4: ++ return 400; ++ case 5: ++ return 533; ++ case 6: ++ return 667; ++ case 7: ++ return 800; ++ default: ++ return 0; ++ } ++ } else { ++ return 0; + } + } + +@@ -1046,6 +1065,34 @@ 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]); + 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)) { ++ /* 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]; ++ } + t->memory_error_information_handle = 0xFFFE; /* no error information handle available */ + single_len = t->length + smbios_string_table_len(t->eos); + len += single_len; +diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c +index 0c06444..303c6c7 100644 +--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c ++++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c +@@ -327,6 +327,9 @@ restartinit: + printk(BIOS_DEBUG, "No Nodes?!\n"); + goto fatalexit; + } ++ ++ printk(BIOS_DEBUG, "mctAutoInitMCT_D: DIMMSetVoltage\n"); ++ DIMMSetVoltages(pMCTstat, pDCTstatA); /* Set the DIMM voltages (mainboard specific) */ + + printk(BIOS_DEBUG, "mctAutoInitMCT_D: SyncDCTsReady_D\n"); + SyncDCTsReady_D(pMCTstat, pDCTstatA); /* Make sure DCTs are ready for accesses.*/ +@@ -2120,6 +2123,9 @@ static u8 DIMMPresence_D(struct MCTStatStruc *pMCTstat, + pDCTstat->DimmBanks[i] = 1ULL << (((mctRead_SPD(smbaddr, SPD_Density) & 0x70) >> 4) + 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 */ + byte = mctRead_SPD(smbaddr, SPD_DIMMTYPE) & 0x7; + if (byte == JED_RDIMM || byte == JED_MiniRDIMM) { +diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h +index c790d7e..a947c2d 100644 +--- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h ++++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.h +@@ -206,6 +206,7 @@ + #define JED_MiniRDIMM 0x5 /* Mini-RDIMM */ + #define SPD_Density 4 /* Bank address bits,SDRAM capacity */ + #define SPD_Addressing 5 /* Row/Column address bits */ ++#define SPD_Voltage 6 /* Supported voltage bitfield */ + #define SPD_Organization 7 /* rank#,Device width */ + #define SPD_BusWidth 8 /* ECC, Bus width */ + #define JED_ECC 8 /* ECC capability */ +@@ -585,6 +586,10 @@ struct DCTStatStruc { /* A per Node structure*/ + struct _sDCTStruct s_C_DCTPtr[2]; + /* 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 DimmCols[MAX_DIMMS_SUPPORTED]; + uint8_t DimmRanks[MAX_DIMMS_SUPPORTED]; +@@ -905,6 +910,7 @@ u32 procOdtWorkaround(struct DCTStatStruc *pDCTstat, u32 dct, u32 val); + void mct_BeforeDramInit_D(struct DCTStatStruc *pDCTstat, u32 dct); + void mctGet_DIMMAddr(struct DCTStatStruc *pDCTstat, u32 node); + void mctSMBhub_Init(u32 node); ++void DIMMSetVoltages(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); + int mctRead_SPD(u32 smaddr, u32 reg); + void InterleaveNodes_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); + void InterleaveChannels_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA); +-- +1.7.9.5 + |