EDAC, amd64: Determine EDAC capabilities on Fam17h systems
authorYazen Ghannam <Yazen.Ghannam@amd.com>
Thu, 17 Nov 2016 22:57:40 +0000 (17:57 -0500)
committerBorislav Petkov <bp@suse.de>
Tue, 29 Nov 2016 17:05:47 +0000 (18:05 +0100)
We need to determine the EDAC capabilities from all UMCs on the node. We
should only check UMCs that are enabled and make sure they all agree.

Signed-off-by: Yazen Ghannam <Yazen.Ghannam@amd.com>
Cc: Aravind Gopalakrishnan <aravindksg.lkml@gmail.com>
Cc: linux-edac <linux-edac@vger.kernel.org>
Cc: x86-ml <x86@kernel.org>
Link: http://lkml.kernel.org/r/1479423463-8536-15-git-send-email-Yazen.Ghannam@amd.com
Signed-off-by: Borislav Petkov <bp@suse.de>
drivers/edac/amd64_edac.c

index 9f9d2bc..d7bd96c 100644 (file)
@@ -715,15 +715,33 @@ static int get_channel_from_ecc_syndrome(struct mem_ctl_info *, u16);
  */
 static unsigned long determine_edac_cap(struct amd64_pvt *pvt)
 {
-       u8 bit;
        unsigned long edac_cap = EDAC_FLAG_NONE;
+       u8 bit;
 
-       bit = (pvt->fam > 0xf || pvt->ext_model >= K8_REV_F)
-               ? 19
-               : 17;
+       if (pvt->umc) {
+               u8 i, umc_en_mask = 0, dimm_ecc_en_mask = 0;
 
-       if (pvt->dclr0 & BIT(bit))
-               edac_cap = EDAC_FLAG_SECDED;
+               for (i = 0; i < NUM_UMCS; i++) {
+                       if (!(pvt->umc[i].sdp_ctrl & UMC_SDP_INIT))
+                               continue;
+
+                       umc_en_mask |= BIT(i);
+
+                       /* UMC Configuration bit 12 (DimmEccEn) */
+                       if (pvt->umc[i].umc_cfg & BIT(12))
+                               dimm_ecc_en_mask |= BIT(i);
+               }
+
+               if (umc_en_mask == dimm_ecc_en_mask)
+                       edac_cap = EDAC_FLAG_SECDED;
+       } else {
+               bit = (pvt->fam > 0xf || pvt->ext_model >= K8_REV_F)
+                       ? 19
+                       : 17;
+
+               if (pvt->dclr0 & BIT(bit))
+                       edac_cap = EDAC_FLAG_SECDED;
+       }
 
        return edac_cap;
 }