aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c
diff options
context:
space:
mode:
authorTimothy Pearson <tpearson@raptorengineeringinc.com>2015-06-10 10:46:17 -0500
committerStefan Reinauer <stefan.reinauer@coreboot.org>2015-11-12 00:51:23 +0100
commitf70946ff4d70d763ce75bf3876bc94dc708275b1 (patch)
treeb75f957e19a6cc75a8f86c5a480d8f3348baeaad /src/northbridge/amd/amdmct/mct_ddr3/s3utils.c
parentab87c4db30acda329d010ac9e91d0bb8b9c6c1cc (diff)
northbridge/amd/amdmct: Verify MCT NVRAM options before skipping training
Change-Id: If26e5d148a906d63bd1407b8ffa58f08ae6b4275 Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> Reviewed-on: http://review.coreboot.org/11986 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/northbridge/amd/amdmct/mct_ddr3/s3utils.c')
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/s3utils.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c b/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c
index 0a508cb406..6e92f3a2fc 100644
--- a/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c
+++ b/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c
@@ -139,6 +139,36 @@ void calculate_spd_hash(uint8_t *spd_data, uint64_t *spd_hash)
*spd_hash = *spd_hash ^ (*spd_hash << 37);
}
+uint16_t calculate_nvram_mct_hash(void)
+{
+ uint32_t nvram;
+ uint16_t ret;
+
+ ret = 0;
+ if (get_option(&nvram, "max_mem_clock") == CB_SUCCESS)
+ ret |= nvram & 0xf;
+ if (get_option(&nvram, "minimum_memory_voltage") == CB_SUCCESS)
+ ret |= (nvram & 0x3) << 4;
+ if (get_option(&nvram, "ECC_memory") == CB_SUCCESS)
+ ret |= (nvram & 0x1) << 6;
+ if (get_option(&nvram, "ECC_redirection") == CB_SUCCESS)
+ ret |= (nvram & 0x1) << 7;
+ if (get_option(&nvram, "ecc_scrub_rate") == CB_SUCCESS)
+ ret |= (nvram & 0x1) << 8;
+ if (get_option(&nvram, "interleave_chip_selects") == CB_SUCCESS)
+ ret |= (nvram & 0x1) << 9;
+ if (get_option(&nvram, "interleave_nodes") == CB_SUCCESS)
+ ret |= (nvram & 0x1) << 10;
+ if (get_option(&nvram, "interleave_memory_channels") == CB_SUCCESS)
+ ret |= (nvram & 0x1) << 11;
+ if (get_option(&nvram, "cpu_c_states") == CB_SUCCESS)
+ ret |= (nvram & 0x1) << 12;
+ if (get_option(&nvram, "cpu_cc6_state") == CB_SUCCESS)
+ ret |= (nvram & 0x1) << 13;
+
+ return ret;
+}
+
static struct amd_s3_persistent_data * map_s3nv_in_nvram(void)
{
ssize_t s3nv_offset;
@@ -169,7 +199,7 @@ static struct amd_s3_persistent_data * map_s3nv_in_nvram(void)
}
#ifdef __PRE_RAM__
-int8_t load_spd_hashes_from_nvram(struct DCTStatStruc *pDCTstat)
+int8_t load_spd_hashes_from_nvram(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat)
{
struct amd_s3_persistent_data *persistent_data;
@@ -180,6 +210,8 @@ int8_t load_spd_hashes_from_nvram(struct DCTStatStruc *pDCTstat)
memcpy(pDCTstat->spd_data.nvram_spd_hash, persistent_data->node[pDCTstat->Node_ID].spd_hash, sizeof(pDCTstat->spd_data.nvram_spd_hash));
memcpy(pDCTstat->spd_data.nvram_memclk, persistent_data->node[pDCTstat->Node_ID].memclk, sizeof(pDCTstat->spd_data.nvram_memclk));
+ pMCTstat->nvram_checksum = persistent_data->nvram_checksum;
+
return 0;
}
#endif
@@ -233,6 +265,8 @@ static void copy_cbmem_spd_data_to_save_variable(struct amd_s3_persistent_data*
for (channel = 0; channel < 2; channel++)
persistent_data->node[node].memclk[channel] = mem_info->dct_stat[node].Speed;
+ persistent_data->nvram_checksum = calculate_nvram_mct_hash();
+
if (restored) {
if (mem_info->mct_stat.GStatus & (1 << GSB_ConfigRestored))
*restored = 1;