Commit eb77e6b8 authored by Yazen Ghannam's avatar Yazen Ghannam Committed by Borislav Petkov

EDAC, amd64: Fix reporting of Chip Select sizes on Fam17h

The wrong index into the csbases/csmasks arrays was being passed to
the function to compute the chip select sizes, which resulted in the
wrong size being computed. Address that so that the correct values are
computed and printed.

Also, redo how we calculate the number of pages in a CS row.
Reported-by: default avatarBenjamin Bennett <benbennett@gmail.com>
Signed-off-by: default avatarYazen Ghannam <yazen.ghannam@amd.com>
Cc: <stable@vger.kernel.org> # 4.10.x
Cc: linux-edac <linux-edac@vger.kernel.org>
Link: http://lkml.kernel.org/r/1493313114-11260-1-git-send-email-Yazen.Ghannam@amd.com
[ Remove unneeded integer math comment, minor cleanups. ]
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
parent f8d5549d
...@@ -782,24 +782,26 @@ static void debug_dump_dramcfg_low(struct amd64_pvt *pvt, u32 dclr, int chan) ...@@ -782,24 +782,26 @@ static void debug_dump_dramcfg_low(struct amd64_pvt *pvt, u32 dclr, int chan)
static void debug_display_dimm_sizes_df(struct amd64_pvt *pvt, u8 ctrl) static void debug_display_dimm_sizes_df(struct amd64_pvt *pvt, u8 ctrl)
{ {
u32 *dcsb = ctrl ? pvt->csels[1].csbases : pvt->csels[0].csbases; int dimm, size0, size1, cs0, cs1;
int dimm, size0, size1;
edac_printk(KERN_DEBUG, EDAC_MC, "UMC%d chip selects:\n", ctrl); edac_printk(KERN_DEBUG, EDAC_MC, "UMC%d chip selects:\n", ctrl);
for (dimm = 0; dimm < 4; dimm++) { for (dimm = 0; dimm < 4; dimm++) {
size0 = 0; size0 = 0;
cs0 = dimm * 2;
if (dcsb[dimm*2] & DCSB_CS_ENABLE) if (csrow_enabled(cs0, ctrl, pvt))
size0 = pvt->ops->dbam_to_cs(pvt, ctrl, 0, dimm); size0 = pvt->ops->dbam_to_cs(pvt, ctrl, 0, cs0);
size1 = 0; size1 = 0;
if (dcsb[dimm*2 + 1] & DCSB_CS_ENABLE) cs1 = dimm * 2 + 1;
size1 = pvt->ops->dbam_to_cs(pvt, ctrl, 0, dimm);
if (csrow_enabled(cs1, ctrl, pvt))
size1 = pvt->ops->dbam_to_cs(pvt, ctrl, 0, cs1);
amd64_info(EDAC_MC ": %d: %5dMB %d: %5dMB\n", amd64_info(EDAC_MC ": %d: %5dMB %d: %5dMB\n",
dimm * 2, size0, cs0, size0,
dimm * 2 + 1, size1); cs1, size1);
} }
} }
...@@ -2756,26 +2758,22 @@ static void read_mc_regs(struct amd64_pvt *pvt) ...@@ -2756,26 +2758,22 @@ static void read_mc_regs(struct amd64_pvt *pvt)
* encompasses * encompasses
* *
*/ */
static u32 get_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr) static u32 get_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr_orig)
{ {
u32 cs_mode, nr_pages;
u32 dbam = dct ? pvt->dbam1 : pvt->dbam0; u32 dbam = dct ? pvt->dbam1 : pvt->dbam0;
int csrow_nr = csrow_nr_orig;
u32 cs_mode, nr_pages;
if (!pvt->umc)
csrow_nr >>= 1;
/* cs_mode = DBAM_DIMM(csrow_nr, dbam);
* The math on this doesn't look right on the surface because x/2*4 can
* be simplified to x*2 but this expression makes use of the fact that
* it is integral math where 1/2=0. This intermediate value becomes the
* number of bits to shift the DBAM register to extract the proper CSROW
* field.
*/
cs_mode = DBAM_DIMM(csrow_nr / 2, dbam);
nr_pages = pvt->ops->dbam_to_cs(pvt, dct, cs_mode, (csrow_nr / 2)) nr_pages = pvt->ops->dbam_to_cs(pvt, dct, cs_mode, csrow_nr);
<< (20 - PAGE_SHIFT); nr_pages <<= 20 - PAGE_SHIFT;
edac_dbg(0, "csrow: %d, channel: %d, DBAM idx: %d\n", edac_dbg(0, "csrow: %d, channel: %d, DBAM idx: %d\n",
csrow_nr, dct, cs_mode); csrow_nr_orig, dct, cs_mode);
edac_dbg(0, "nr_pages/channel: %u\n", nr_pages); edac_dbg(0, "nr_pages/channel: %u\n", nr_pages);
return nr_pages; return nr_pages;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment