diff options
Diffstat (limited to 'drivers/edac/amd64_edac.c')
-rw-r--r-- | drivers/edac/amd64_edac.c | 50 |
1 files changed, 40 insertions, 10 deletions
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index ca1d63aa4e59..870f56713c22 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -2664,20 +2664,50 @@ static const char *ecc_msg = static bool ecc_enabled(struct pci_dev *F3, u16 nid) { - u32 value; - u8 ecc_en = 0; bool nb_mce_en = false; + u8 ecc_en = 0, i; + u32 value; - amd64_read_pci_cfg(F3, NBCFG, &value); + if (boot_cpu_data.x86 >= 0x17) { + u8 umc_en_mask = 0, ecc_en_mask = 0; - ecc_en = !!(value & NBCFG_ECC_ENABLE); - amd64_info("DRAM ECC %s.\n", (ecc_en ? "enabled" : "disabled")); + for (i = 0; i < NUM_UMCS; i++) { + u32 base = get_umc_base(i); + + /* Only check enabled UMCs. */ + if (amd_smn_read(nid, base + UMCCH_SDP_CTRL, &value)) + continue; + + if (!(value & UMC_SDP_INIT)) + continue; + + umc_en_mask |= BIT(i); + + if (amd_smn_read(nid, base + UMCCH_UMC_CAP_HI, &value)) + continue; + + if (value & UMC_ECC_ENABLED) + ecc_en_mask |= BIT(i); + } + + /* Check whether at least one UMC is enabled: */ + if (umc_en_mask) + ecc_en = umc_en_mask == ecc_en_mask; + + /* Assume UMC MCA banks are enabled. */ + nb_mce_en = true; + } else { + amd64_read_pci_cfg(F3, NBCFG, &value); - nb_mce_en = nb_mce_bank_enabled_on_node(nid); - if (!nb_mce_en) - amd64_notice("NB MCE bank disabled, set MSR " - "0x%08x[4] on node %d to enable.\n", - MSR_IA32_MCG_CTL, nid); + ecc_en = !!(value & NBCFG_ECC_ENABLE); + + nb_mce_en = nb_mce_bank_enabled_on_node(nid); + if (!nb_mce_en) + amd64_notice("NB MCE bank disabled, set MSR 0x%08x[4] on node %d to enable.\n", + MSR_IA32_MCG_CTL, nid); + } + + amd64_info("DRAM ECC %s.\n", (ecc_en ? "enabled" : "disabled")); if (!ecc_en || !nb_mce_en) { amd64_notice("%s", ecc_msg); |