aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/edac/amd64_edac.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index d89998dcf7f5..4c0239aeff2f 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -787,6 +787,22 @@ static void debug_dump_dramcfg_low(struct amd64_pvt *pvt, u32 dclr, int chan)
787 (dclr & BIT(15)) ? "yes" : "no"); 787 (dclr & BIT(15)) ? "yes" : "no");
788} 788}
789 789
790/*
791 * The Address Mask should be a contiguous set of bits in the non-interleaved
792 * case. So to check for CS interleaving, find the most- and least-significant
793 * bits of the mask, generate a contiguous bitmask, and compare the two.
794 */
795static bool f17_cs_interleaved(struct amd64_pvt *pvt, u8 ctrl, int cs)
796{
797 u32 mask = pvt->csels[ctrl].csmasks[cs >> 1];
798 u32 msb = fls(mask) - 1, lsb = ffs(mask) - 1;
799 u32 test_mask = GENMASK(msb, lsb);
800
801 edac_dbg(1, "mask=0x%08x test_mask=0x%08x\n", mask, test_mask);
802
803 return mask ^ test_mask;
804}
805
790static void debug_display_dimm_sizes_df(struct amd64_pvt *pvt, u8 ctrl) 806static void debug_display_dimm_sizes_df(struct amd64_pvt *pvt, u8 ctrl)
791{ 807{
792 int dimm, size0, size1, cs0, cs1; 808 int dimm, size0, size1, cs0, cs1;
@@ -803,8 +819,19 @@ static void debug_display_dimm_sizes_df(struct amd64_pvt *pvt, u8 ctrl)
803 size1 = 0; 819 size1 = 0;
804 cs1 = dimm * 2 + 1; 820 cs1 = dimm * 2 + 1;
805 821
806 if (csrow_enabled(cs1, ctrl, pvt)) 822 if (csrow_enabled(cs1, ctrl, pvt)) {
807 size1 = pvt->ops->dbam_to_cs(pvt, ctrl, 0, cs1); 823 /*
824 * CS interleaving is only supported if both CSes have
825 * the same amount of memory. Because they are
826 * interleaved, it will look like both CSes have the
827 * full amount of memory. Save the size for both as
828 * half the amount we found on CS0, if interleaved.
829 */
830 if (f17_cs_interleaved(pvt, ctrl, cs1))
831 size1 = size0 = (size0 >> 1);
832 else
833 size1 = pvt->ops->dbam_to_cs(pvt, ctrl, 0, cs1);
834 }
808 835
809 amd64_info(EDAC_MC ": %d: %5dMB %d: %5dMB\n", 836 amd64_info(EDAC_MC ": %d: %5dMB %d: %5dMB\n",
810 cs0, size0, 837 cs0, size0,