diff options
author | Francis Rowe <info@gluglug.org.uk> | 2015-10-17 11:10:53 (EDT) |
---|---|---|
committer | Francis Rowe <info@gluglug.org.uk> | 2015-10-17 14:07:35 (EDT) |
commit | 5999dba5f71f1c05040a551d2420ab8c7f3a9da4 (patch) | |
tree | 7313b1996a247bf938417d5cf2496f5f6625c0db /resources/libreboot/patch/kgpe-d16/0075-northbridge-amd-amdmct-mct_ddr3-Attempt-to-recover-f.patch | |
parent | 4d909153e79661e54999e51693668f6d1ecc1cca (diff) | |
download | libreboot-5999dba5f71f1c05040a551d2420ab8c7f3a9da4.zip libreboot-5999dba5f71f1c05040a551d2420ab8c7f3a9da4.tar.gz libreboot-5999dba5f71f1c05040a551d2420ab8c7f3a9da4.tar.bz2 |
New board: ASUS KGPE-D16
coreboot build errors:
In file included from src/northbridge/amd/amdfam10/misc_control.c:35:0:
src/include/option.h:13:27: error: static declaration of 'get_option' follows non-static declaration
static inline enum cb_err get_option(void *dest, const char *name)
^
In file included from src/northbridge/amd/amdfam10/misc_control.c:34:0:
src/include/pc80/mc146818rtc.h:176:13: note: previous declaration of 'get_option' was here
enum cb_err get_option(void *dest, const char *name);
Ping tpearson about this.
Also ping him about the fact that there isn't actually an option to
enable or disable native graphics initialization, but that the option
MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG is in fact available and set to Y in the
Kconfig file. I think this is probably since there isn't even an option
ROM available for the machine, so it's pointless to offer the setting.
Diffstat (limited to 'resources/libreboot/patch/kgpe-d16/0075-northbridge-amd-amdmct-mct_ddr3-Attempt-to-recover-f.patch')
-rw-r--r-- | resources/libreboot/patch/kgpe-d16/0075-northbridge-amd-amdmct-mct_ddr3-Attempt-to-recover-f.patch | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/resources/libreboot/patch/kgpe-d16/0075-northbridge-amd-amdmct-mct_ddr3-Attempt-to-recover-f.patch b/resources/libreboot/patch/kgpe-d16/0075-northbridge-amd-amdmct-mct_ddr3-Attempt-to-recover-f.patch new file mode 100644 index 0000000..6436922 --- /dev/null +++ b/resources/libreboot/patch/kgpe-d16/0075-northbridge-amd-amdmct-mct_ddr3-Attempt-to-recover-f.patch @@ -0,0 +1,254 @@ +From 46ebd28412a108fc6329118acb53345b44feea4c Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <kb9vqf@pearsoncomputing.net> +Date: Thu, 25 Jun 2015 18:08:53 -0500 +Subject: [PATCH 075/146] northbridge/amd/amdmct/mct_ddr3: Attempt to recover + from phy training errors + +--- + src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c | 68 +++++++++++++++++++------ + src/northbridge/amd/amdmct/mct_ddr3/mhwlc_d.c | 36 ++++++++++--- + 2 files changed, 83 insertions(+), 21 deletions(-) + +diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c b/src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c +index 5e81808..539cb0d 100644 +--- a/src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c ++++ b/src/northbridge/amd/amdmct/mct_ddr3/mcthwl.c +@@ -18,11 +18,11 @@ + * Foundation, Inc. + */ + +-static void AgesaHwWlPhase1(struct MCTStatStruc *pMCTstat, ++static uint8_t AgesaHwWlPhase1(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstat, u8 dct, u8 dimm, u8 pass); +-static void AgesaHwWlPhase2(struct MCTStatStruc *pMCTstat, ++static uint8_t AgesaHwWlPhase2(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstat, u8 dct, u8 dimm, u8 pass); +-static void AgesaHwWlPhase3(struct MCTStatStruc *pMCTstat, ++static uint8_t AgesaHwWlPhase3(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstat, u8 dct, u8 dimm, u8 pass); + static void EnableZQcalibration(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); + static void DisableZQcalibration(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); +@@ -100,11 +100,12 @@ static void DisableAutoRefresh_D(struct MCTStatStruc *pMCTstat, + } + + +-static void PhyWLPass1(struct MCTStatStruc *pMCTstat, ++static uint8_t PhyWLPass1(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstat, u8 dct) + { + u8 dimm; + u16 DIMMValid; ++ uint8_t status = 0; + void *DCTPtr; + + dct &= 1; +@@ -121,19 +122,22 @@ static void PhyWLPass1(struct MCTStatStruc *pMCTstat, + PrepareC_DCT(pMCTstat, pDCTstat, dct); + for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm ++) { + if (DIMMValid & (1 << (dimm << 1))) { +- AgesaHwWlPhase1(pMCTstat, pDCTstat, dct, dimm, FirstPass); +- AgesaHwWlPhase2(pMCTstat, pDCTstat, dct, dimm, FirstPass); +- AgesaHwWlPhase3(pMCTstat, pDCTstat, dct, dimm, FirstPass); ++ status |= AgesaHwWlPhase1(pMCTstat, pDCTstat, dct, dimm, FirstPass); ++ status |= AgesaHwWlPhase2(pMCTstat, pDCTstat, dct, dimm, FirstPass); ++ status |= AgesaHwWlPhase3(pMCTstat, pDCTstat, dct, dimm, FirstPass); + } + } + } ++ ++ return status; + } + +-static void PhyWLPass2(struct MCTStatStruc *pMCTstat, ++static uint8_t PhyWLPass2(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstat, u8 dct) + { + u8 dimm; + u16 DIMMValid; ++ uint8_t status = 0; + void *DCTPtr; + + dct &= 1; +@@ -163,12 +167,14 @@ static void PhyWLPass2(struct MCTStatStruc *pMCTstat, + DisableAutoRefresh_D(pMCTstat, pDCTstat); + for (dimm = 0; dimm < MAX_DIMMS_SUPPORTED; dimm ++) { + if (DIMMValid & (1 << (dimm << 1))) { +- AgesaHwWlPhase1(pMCTstat, pDCTstat, dct, dimm, SecondPass); +- AgesaHwWlPhase2(pMCTstat, pDCTstat, dct, dimm, SecondPass); +- AgesaHwWlPhase3(pMCTstat, pDCTstat, dct, dimm, SecondPass); ++ status |= AgesaHwWlPhase1(pMCTstat, pDCTstat, dct, dimm, SecondPass); ++ status |= AgesaHwWlPhase2(pMCTstat, pDCTstat, dct, dimm, SecondPass); ++ status |= AgesaHwWlPhase3(pMCTstat, pDCTstat, dct, dimm, SecondPass); + } + } + } ++ ++ return status; + } + + static uint16_t fam15h_next_highest_memclk_freq(uint16_t memclk_freq) +@@ -183,6 +189,8 @@ static uint16_t fam15h_next_highest_memclk_freq(uint16_t memclk_freq) + static void WriteLevelization_HW(struct MCTStatStruc *pMCTstat, + struct DCTStatStruc *pDCTstat, uint8_t Pass) + { ++ uint8_t status; ++ uint8_t timeout; + uint16_t final_target_freq; + + pDCTstat->C_MCTPtr = &(pDCTstat->s_C_MCTPtr); +@@ -201,8 +209,21 @@ static void WriteLevelization_HW(struct MCTStatStruc *pMCTstat, + } + + if (Pass == FirstPass) { +- PhyWLPass1(pMCTstat, pDCTstat, 0); +- PhyWLPass1(pMCTstat, pDCTstat, 1); ++ timeout = 0; ++ do { ++ status = 0; ++ timeout++; ++ status |= PhyWLPass1(pMCTstat, pDCTstat, 0); ++ status |= PhyWLPass1(pMCTstat, pDCTstat, 1); ++ if (status) ++ printk(BIOS_INFO, ++ "%s: Retrying write levelling due to invalid value(s) detected in first phase\n", ++ __func__); ++ } while (status && (timeout < 8)); ++ if (status) ++ printk(BIOS_INFO, ++ "%s: Uncorrectable invalid value(s) detected in first phase of write levelling\n", ++ __func__); + } + + if (Pass == SecondPass) { +@@ -211,6 +232,7 @@ static void WriteLevelization_HW(struct MCTStatStruc *pMCTstat, + * NOTE: BIOS must program both DCTs to the same frequency. + * NOTE: Fam15h steps the frequency, Fam10h slams the frequency. + */ ++ uint8_t global_phy_training_status = 0; + final_target_freq = pDCTstat->TargetFreq; + + while (pDCTstat->Speed != final_target_freq) { +@@ -219,12 +241,28 @@ static void WriteLevelization_HW(struct MCTStatStruc *pMCTstat, + else + pDCTstat->TargetFreq = final_target_freq; + SetTargetFreq(pMCTstat, pDCTstat); +- PhyWLPass2(pMCTstat, pDCTstat, 0); +- PhyWLPass2(pMCTstat, pDCTstat, 1); ++ timeout = 0; ++ do { ++ status = 0; ++ timeout++; ++ status |= PhyWLPass2(pMCTstat, pDCTstat, 0); ++ status |= PhyWLPass2(pMCTstat, pDCTstat, 1); ++ if (status) ++ printk(BIOS_INFO, ++ "%s: Retrying write levelling due to invalid value(s) detected in last phase\n", ++ __func__); ++ } while (status && (timeout < 8)); ++ global_phy_training_status |= status; + } + + pDCTstat->TargetFreq = final_target_freq; + ++ if (global_phy_training_status) ++ printk(BIOS_WARNING, ++ "%s: Uncorrectable invalid value(s) detected in second phase of write levelling; " ++ "continuing but system may be unstable!\n", ++ __func__); ++ + uint8_t dct; + for (dct = 0; dct < 2; dct++) { + sDCTStruct *pDCTData = pDCTstat->C_DCTPtr[dct]; +diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mhwlc_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mhwlc_d.c +index 3995a70..72c74e6 100644 +--- a/src/northbridge/amd/amdmct/mct_ddr3/mhwlc_d.c ++++ b/src/northbridge/amd/amdmct/mct_ddr3/mhwlc_d.c +@@ -54,7 +54,7 @@ static int32_t abs(int32_t val) { + */ + + /*----------------------------------------------------------------------------- +- * void AgesaHwWlPhase1(SPDStruct *SPDData,MCTStruct *MCTData, DCTStruct *DCTData, ++ * uint8_t AgesaHwWlPhase1(SPDStruct *SPDData,MCTStruct *MCTData, DCTStruct *DCTData, + * u8 Dimm, u8 Pass) + * + * Description: +@@ -71,7 +71,7 @@ static int32_t abs(int32_t val) { + * OUT + *----------------------------------------------------------------------------- + */ +-void AgesaHwWlPhase1(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, ++uint8_t AgesaHwWlPhase1(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, + u8 dct, u8 dimm, u8 pass) + { + u8 ByteLane; +@@ -174,12 +174,15 @@ void AgesaHwWlPhase1(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTsta + } + + pDCTData->WLCriticalGrossDelayPrevPass = 0x1f; ++ ++ return 0; + } + +-void AgesaHwWlPhase2(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, ++uint8_t AgesaHwWlPhase2(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, + u8 dct, u8 dimm, u8 pass) + { + u8 ByteLane; ++ uint8_t status = 0; + sDCTStruct *pDCTData = pDCTstat->C_DCTPtr[dct]; + + if (is_fam15h()) { +@@ -206,19 +209,38 @@ void AgesaHwWlPhase2(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTsta + + /* Compensate for occasional noise/instability causing sporadic training failure */ + for (ByteLane = 0; ByteLane < MAX_BYTE_LANES; ByteLane++) { ++ uint8_t faulty_value_detected = 0; + uint16_t total_delay_seed = ((pDCTData->WLSeedGrossDelay[index+ByteLane] & 0x1f) << 5) | (pDCTData->WLSeedFineDelay[index+ByteLane] & 0x1f); + uint16_t total_delay_phy = ((pDCTData->WLGrossDelay[index+ByteLane] & 0x1f) << 5) | (pDCTData->WLFineDelay[index+ByteLane] & 0x1f); +- if (abs(total_delay_phy - total_delay_seed) > 0x20) { +- printk(BIOS_DEBUG, "%s: overriding faulty phy value (seed: %04x phy: %04x step: %04x)\n", __func__, ++ if (pass == FirstPass) { ++ /* Allow a somewhat higher step threshold on the first pass ++ * For the most part, as long as the phy isn't stepping ++ * several clocks at once the values are probably valid. ++ */ ++ if (abs(total_delay_phy - total_delay_seed) > 0x30) ++ faulty_value_detected = 1; ++ } else { ++ /* Stepping memory clocks between adjacent allowed frequencies ++ * should not yield large phy value differences... ++ */ ++ ++ if (abs(total_delay_phy - total_delay_seed) > 0x20) ++ faulty_value_detected = 1; ++ } ++ if (faulty_value_detected) { ++ printk(BIOS_INFO, "%s: overriding faulty phy value (seed: %04x phy: %04x step: %04x)\n", __func__, + total_delay_seed, total_delay_phy, abs(total_delay_phy - total_delay_seed)); + pDCTData->WLGrossDelay[index+ByteLane] = pDCTData->WLSeedGrossDelay[index+ByteLane]; + pDCTData->WLFineDelay[index+ByteLane] = pDCTData->WLSeedFineDelay[index+ByteLane]; ++ status = 1; + } + } + } ++ ++ return status; + } + +-void AgesaHwWlPhase3(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, ++uint8_t AgesaHwWlPhase3(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, + u8 dct, u8 dimm, u8 pass) + { + u8 ByteLane; +@@ -285,6 +307,8 @@ void AgesaHwWlPhase3(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTsta + * to the normal operating termination: + */ + prepareDimms(pMCTstat, pDCTstat, dct, dimm, FALSE); ++ ++ return 0; + } + + /*---------------------------------------------------------------------------- +-- +1.7.9.5 + |