diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/edac/amd64_edac.c | 31 |
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 | */ | ||
| 795 | static 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 | |||
| 790 | static void debug_display_dimm_sizes_df(struct amd64_pvt *pvt, u8 ctrl) | 806 | static 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, |
