aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYazen Ghannam <yazen.ghannam@amd.com>2017-04-27 13:11:54 -0400
committerBorislav Petkov <bp@suse.de>2017-05-03 10:27:36 -0400
commiteb77e6b80f3bed262c7773236f0fb84649fd3091 (patch)
tree38f7f443238317c86c10394f1e415519e7e083e2
parentf8d5549df25e3961d6bd2ae36d3e0b08614660d9 (diff)
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: Benjamin Bennett <benbennett@gmail.com> Signed-off-by: Yazen 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: Borislav Petkov <bp@suse.de>
-rw-r--r--drivers/edac/amd64_edac.c40
1 files changed, 19 insertions, 21 deletions
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 82dab1692264..3aea55698165 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -782,24 +782,26 @@ static void debug_dump_dramcfg_low(struct amd64_pvt *pvt, u32 dclr, int chan)
782 782
783static void debug_display_dimm_sizes_df(struct amd64_pvt *pvt, u8 ctrl) 783static void debug_display_dimm_sizes_df(struct amd64_pvt *pvt, u8 ctrl)
784{ 784{
785 u32 *dcsb = ctrl ? pvt->csels[1].csbases : pvt->csels[0].csbases; 785 int dimm, size0, size1, cs0, cs1;
786 int dimm, size0, size1;
787 786
788 edac_printk(KERN_DEBUG, EDAC_MC, "UMC%d chip selects:\n", ctrl); 787 edac_printk(KERN_DEBUG, EDAC_MC, "UMC%d chip selects:\n", ctrl);
789 788
790 for (dimm = 0; dimm < 4; dimm++) { 789 for (dimm = 0; dimm < 4; dimm++) {
791 size0 = 0; 790 size0 = 0;
791 cs0 = dimm * 2;
792 792
793 if (dcsb[dimm*2] & DCSB_CS_ENABLE) 793 if (csrow_enabled(cs0, ctrl, pvt))
794 size0 = pvt->ops->dbam_to_cs(pvt, ctrl, 0, dimm); 794 size0 = pvt->ops->dbam_to_cs(pvt, ctrl, 0, cs0);
795 795
796 size1 = 0; 796 size1 = 0;
797 if (dcsb[dimm*2 + 1] & DCSB_CS_ENABLE) 797 cs1 = dimm * 2 + 1;
798 size1 = pvt->ops->dbam_to_cs(pvt, ctrl, 0, dimm); 798
799 if (csrow_enabled(cs1, ctrl, pvt))
800 size1 = pvt->ops->dbam_to_cs(pvt, ctrl, 0, cs1);
799 801
800 amd64_info(EDAC_MC ": %d: %5dMB %d: %5dMB\n", 802 amd64_info(EDAC_MC ": %d: %5dMB %d: %5dMB\n",
801 dimm * 2, size0, 803 cs0, size0,
802 dimm * 2 + 1, size1); 804 cs1, size1);
803 } 805 }
804} 806}
805 807
@@ -2756,26 +2758,22 @@ skip:
2756 * encompasses 2758 * encompasses
2757 * 2759 *
2758 */ 2760 */
2759static u32 get_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr) 2761static u32 get_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr_orig)
2760{ 2762{
2761 u32 cs_mode, nr_pages;
2762 u32 dbam = dct ? pvt->dbam1 : pvt->dbam0; 2763 u32 dbam = dct ? pvt->dbam1 : pvt->dbam0;
2764 int csrow_nr = csrow_nr_orig;
2765 u32 cs_mode, nr_pages;
2763 2766
2767 if (!pvt->umc)
2768 csrow_nr >>= 1;
2764 2769
2765 /* 2770 cs_mode = DBAM_DIMM(csrow_nr, dbam);
2766 * The math on this doesn't look right on the surface because x/2*4 can
2767 * be simplified to x*2 but this expression makes use of the fact that
2768 * it is integral math where 1/2=0. This intermediate value becomes the
2769 * number of bits to shift the DBAM register to extract the proper CSROW
2770 * field.
2771 */
2772 cs_mode = DBAM_DIMM(csrow_nr / 2, dbam);
2773 2771
2774 nr_pages = pvt->ops->dbam_to_cs(pvt, dct, cs_mode, (csrow_nr / 2)) 2772 nr_pages = pvt->ops->dbam_to_cs(pvt, dct, cs_mode, csrow_nr);
2775 << (20 - PAGE_SHIFT); 2773 nr_pages <<= 20 - PAGE_SHIFT;
2776 2774
2777 edac_dbg(0, "csrow: %d, channel: %d, DBAM idx: %d\n", 2775 edac_dbg(0, "csrow: %d, channel: %d, DBAM idx: %d\n",
2778 csrow_nr, dct, cs_mode); 2776 csrow_nr_orig, dct, cs_mode);
2779 edac_dbg(0, "nr_pages/channel: %u\n", nr_pages); 2777 edac_dbg(0, "nr_pages/channel: %u\n", nr_pages);
2780 2778
2781 return nr_pages; 2779 return nr_pages;