summaryrefslogtreecommitdiff
path: root/drivers/edac/amd64_edac.c
diff options
context:
space:
mode:
authorYazen Ghannam <Yazen.Ghannam@amd.com>2016-11-17 17:57:40 -0500
committerBorislav Petkov <bp@suse.de>2016-11-29 18:05:47 +0100
commitd27f3a348e3677b7d5ee6954ebafce679b011164 (patch)
tree2fbfb58db51c8eab72f6776cd3edfd2353b547a0 /drivers/edac/amd64_edac.c
parent2d09d8f301f53cb92e7ae7183d58a74fc55f85c0 (diff)
downloadlwn-d27f3a348e3677b7d5ee6954ebafce679b011164.tar.gz
lwn-d27f3a348e3677b7d5ee6954ebafce679b011164.zip
EDAC, amd64: Determine EDAC capabilities on Fam17h systems
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>
Diffstat (limited to 'drivers/edac/amd64_edac.c')
-rw-r--r--drivers/edac/amd64_edac.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 9f9d2bc1868c..d7bd96c83b51 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -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;
}