aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYazen Ghannam <Yazen.Ghannam@amd.com>2016-11-17 17:57:37 -0500
committerBorislav Petkov <bp@suse.de>2016-11-28 11:50:11 -0500
commitb64ce7cd7f540c64e3fbeaeee3ddb59bc9ab1a3b (patch)
tree3ffab7c868dcf9aa50be60d0b4265f3b0bfe71c1
parent936fc3afaa8abc20dfea306c9b6d19a6e7ca5caf (diff)
EDAC, amd64: Read MC registers on AMD Fam17h
Fam17h has a different set of registers and bitfields. Most of these registers are read through SMN (System Management Network) rather than PCI config space. Also, the derivation of various values is now different. Update amd64_edac to read the appropriate registers and extract the correct values for Fam17h. 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-12-git-send-email-Yazen.Ghannam@amd.com [ Save us the indentation level in read_mc_regs(), add defines ] Signed-off-by: Borislav Petkov <bp@suse.de>
-rw-r--r--drivers/edac/amd64_edac.c172
-rw-r--r--drivers/edac/amd64_edac.h13
2 files changed, 146 insertions, 39 deletions
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 1f3de3402d48..461da1323f2f 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -789,46 +789,78 @@ static void prep_chip_selects(struct amd64_pvt *pvt)
789 */ 789 */
790static void read_dct_base_mask(struct amd64_pvt *pvt) 790static void read_dct_base_mask(struct amd64_pvt *pvt)
791{ 791{
792 int cs; 792 int base_reg0, base_reg1, mask_reg0, mask_reg1, cs;
793 793
794 prep_chip_selects(pvt); 794 prep_chip_selects(pvt);
795 795
796 if (pvt->umc) {
797 base_reg0 = get_umc_base(0) + UMCCH_BASE_ADDR;
798 base_reg1 = get_umc_base(1) + UMCCH_BASE_ADDR;
799 mask_reg0 = get_umc_base(0) + UMCCH_ADDR_MASK;
800 mask_reg1 = get_umc_base(1) + UMCCH_ADDR_MASK;
801 } else {
802 base_reg0 = DCSB0;
803 base_reg1 = DCSB1;
804 mask_reg0 = DCSM0;
805 mask_reg1 = DCSM1;
806 }
807
796 for_each_chip_select(cs, 0, pvt) { 808 for_each_chip_select(cs, 0, pvt) {
797 int reg0 = DCSB0 + (cs * 4); 809 int reg0 = base_reg0 + (cs * 4);
798 int reg1 = DCSB1 + (cs * 4); 810 int reg1 = base_reg1 + (cs * 4);
799 u32 *base0 = &pvt->csels[0].csbases[cs]; 811 u32 *base0 = &pvt->csels[0].csbases[cs];
800 u32 *base1 = &pvt->csels[1].csbases[cs]; 812 u32 *base1 = &pvt->csels[1].csbases[cs];
801 813
802 if (!amd64_read_dct_pci_cfg(pvt, 0, reg0, base0)) 814 if (pvt->umc) {
803 edac_dbg(0, " DCSB0[%d]=0x%08x reg: F2x%x\n", 815 if (!amd_smn_read(pvt->mc_node_id, reg0, base0))
804 cs, *base0, reg0); 816 edac_dbg(0, " DCSB0[%d]=0x%08x reg: 0x%x\n",
817 cs, *base0, reg0);
805 818
806 if (pvt->fam == 0xf) 819 if (!amd_smn_read(pvt->mc_node_id, reg1, base1))
807 continue; 820 edac_dbg(0, " DCSB1[%d]=0x%08x reg: 0x%x\n",
821 cs, *base1, reg1);
822 } else {
823 if (!amd64_read_dct_pci_cfg(pvt, 0, reg0, base0))
824 edac_dbg(0, " DCSB0[%d]=0x%08x reg: F2x%x\n",
825 cs, *base0, reg0);
826
827 if (pvt->fam == 0xf)
828 continue;
808 829
809 if (!amd64_read_dct_pci_cfg(pvt, 1, reg0, base1)) 830 if (!amd64_read_dct_pci_cfg(pvt, 1, reg0, base1))
810 edac_dbg(0, " DCSB1[%d]=0x%08x reg: F2x%x\n", 831 edac_dbg(0, " DCSB1[%d]=0x%08x reg: F2x%x\n",
811 cs, *base1, (pvt->fam == 0x10) ? reg1 832 cs, *base1, (pvt->fam == 0x10) ? reg1
812 : reg0); 833 : reg0);
834 }
813 } 835 }
814 836
815 for_each_chip_select_mask(cs, 0, pvt) { 837 for_each_chip_select_mask(cs, 0, pvt) {
816 int reg0 = DCSM0 + (cs * 4); 838 int reg0 = mask_reg0 + (cs * 4);
817 int reg1 = DCSM1 + (cs * 4); 839 int reg1 = mask_reg1 + (cs * 4);
818 u32 *mask0 = &pvt->csels[0].csmasks[cs]; 840 u32 *mask0 = &pvt->csels[0].csmasks[cs];
819 u32 *mask1 = &pvt->csels[1].csmasks[cs]; 841 u32 *mask1 = &pvt->csels[1].csmasks[cs];
820 842
821 if (!amd64_read_dct_pci_cfg(pvt, 0, reg0, mask0)) 843 if (pvt->umc) {
822 edac_dbg(0, " DCSM0[%d]=0x%08x reg: F2x%x\n", 844 if (!amd_smn_read(pvt->mc_node_id, reg0, mask0))
823 cs, *mask0, reg0); 845 edac_dbg(0, " DCSM0[%d]=0x%08x reg: 0x%x\n",
846 cs, *mask0, reg0);
824 847
825 if (pvt->fam == 0xf) 848 if (!amd_smn_read(pvt->mc_node_id, reg1, mask1))
826 continue; 849 edac_dbg(0, " DCSM1[%d]=0x%08x reg: 0x%x\n",
850 cs, *mask1, reg1);
851 } else {
852 if (!amd64_read_dct_pci_cfg(pvt, 0, reg0, mask0))
853 edac_dbg(0, " DCSM0[%d]=0x%08x reg: F2x%x\n",
854 cs, *mask0, reg0);
855
856 if (pvt->fam == 0xf)
857 continue;
827 858
828 if (!amd64_read_dct_pci_cfg(pvt, 1, reg0, mask1)) 859 if (!amd64_read_dct_pci_cfg(pvt, 1, reg0, mask1))
829 edac_dbg(0, " DCSM1[%d]=0x%08x reg: F2x%x\n", 860 edac_dbg(0, " DCSM1[%d]=0x%08x reg: F2x%x\n",
830 cs, *mask1, (pvt->fam == 0x10) ? reg1 861 cs, *mask1, (pvt->fam == 0x10) ? reg1
831 : reg0); 862 : reg0);
863 }
832 } 864 }
833} 865}
834 866
@@ -881,6 +913,15 @@ static void determine_memory_type(struct amd64_pvt *pvt)
881 case 0x16: 913 case 0x16:
882 goto ddr3; 914 goto ddr3;
883 915
916 case 0x17:
917 if ((pvt->umc[0].dimm_cfg | pvt->umc[1].dimm_cfg) & BIT(5))
918 pvt->dram_type = MEM_LRDDR4;
919 else if ((pvt->umc[0].dimm_cfg | pvt->umc[1].dimm_cfg) & BIT(4))
920 pvt->dram_type = MEM_RDDR4;
921 else
922 pvt->dram_type = MEM_DDR4;
923 return;
924
884 default: 925 default:
885 WARN(1, KERN_ERR "%s: Family??? 0x%x\n", __func__, pvt->fam); 926 WARN(1, KERN_ERR "%s: Family??? 0x%x\n", __func__, pvt->fam);
886 pvt->dram_type = MEM_EMPTY; 927 pvt->dram_type = MEM_EMPTY;
@@ -2341,30 +2382,91 @@ static void free_mc_sibling_devs(struct amd64_pvt *pvt)
2341 } 2382 }
2342} 2383}
2343 2384
2385static void determine_ecc_sym_sz(struct amd64_pvt *pvt)
2386{
2387 pvt->ecc_sym_sz = 4;
2388
2389 if (pvt->umc) {
2390 u8 i;
2391
2392 for (i = 0; i < NUM_UMCS; i++) {
2393 /* Check enabled channels only: */
2394 if ((pvt->umc[i].sdp_ctrl & UMC_SDP_INIT) &&
2395 (pvt->umc[i].ecc_ctrl & BIT(7))) {
2396 pvt->ecc_sym_sz = 8;
2397 break;
2398 }
2399 }
2400
2401 return;
2402 }
2403
2404 if (pvt->fam >= 0x10) {
2405 u32 tmp;
2406
2407 amd64_read_pci_cfg(pvt->F3, EXT_NB_MCA_CFG, &tmp);
2408 /* F16h has only DCT0, so no need to read dbam1. */
2409 if (pvt->fam != 0x16)
2410 amd64_read_dct_pci_cfg(pvt, 1, DBAM0, &pvt->dbam1);
2411
2412 /* F10h, revD and later can do x8 ECC too. */
2413 if ((pvt->fam > 0x10 || pvt->model > 7) && tmp & BIT(25))
2414 pvt->ecc_sym_sz = 8;
2415 }
2416}
2417
2418/*
2419 * Retrieve the hardware registers of the memory controller.
2420 */
2421static void __read_mc_regs_df(struct amd64_pvt *pvt)
2422{
2423 u8 nid = pvt->mc_node_id;
2424 struct amd64_umc *umc;
2425 u32 i, umc_base;
2426
2427 /* Read registers from each UMC */
2428 for (i = 0; i < NUM_UMCS; i++) {
2429
2430 umc_base = get_umc_base(i);
2431 umc = &pvt->umc[i];
2432
2433 amd_smn_read(nid, umc_base + UMCCH_SDP_CTRL, &umc->sdp_ctrl);
2434 amd_smn_read(nid, umc_base + UMCCH_ECC_CTRL, &umc->ecc_ctrl);
2435 amd_smn_read(nid, umc_base + UMCCH_DIMM_CFG, &umc->dimm_cfg);
2436 }
2437}
2438
2344/* 2439/*
2345 * Retrieve the hardware registers of the memory controller (this includes the 2440 * Retrieve the hardware registers of the memory controller (this includes the
2346 * 'Address Map' and 'Misc' device regs) 2441 * 'Address Map' and 'Misc' device regs)
2347 */ 2442 */
2348static void read_mc_regs(struct amd64_pvt *pvt) 2443static void read_mc_regs(struct amd64_pvt *pvt)
2349{ 2444{
2350 unsigned range; 2445 unsigned int range;
2351 u64 msr_val; 2446 u64 msr_val;
2352 u32 tmp;
2353 2447
2354 /* 2448 /*
2355 * Retrieve TOP_MEM and TOP_MEM2; no masking off of reserved bits since 2449 * Retrieve TOP_MEM and TOP_MEM2; no masking off of reserved bits since
2356 * those are Read-As-Zero 2450 * those are Read-As-Zero.
2357 */ 2451 */
2358 rdmsrl(MSR_K8_TOP_MEM1, pvt->top_mem); 2452 rdmsrl(MSR_K8_TOP_MEM1, pvt->top_mem);
2359 edac_dbg(0, " TOP_MEM: 0x%016llx\n", pvt->top_mem); 2453 edac_dbg(0, " TOP_MEM: 0x%016llx\n", pvt->top_mem);
2360 2454
2361 /* check first whether TOP_MEM2 is enabled */ 2455 /* Check first whether TOP_MEM2 is enabled: */
2362 rdmsrl(MSR_K8_SYSCFG, msr_val); 2456 rdmsrl(MSR_K8_SYSCFG, msr_val);
2363 if (msr_val & (1U << 21)) { 2457 if (msr_val & BIT(21)) {
2364 rdmsrl(MSR_K8_TOP_MEM2, pvt->top_mem2); 2458 rdmsrl(MSR_K8_TOP_MEM2, pvt->top_mem2);
2365 edac_dbg(0, " TOP_MEM2: 0x%016llx\n", pvt->top_mem2); 2459 edac_dbg(0, " TOP_MEM2: 0x%016llx\n", pvt->top_mem2);
2366 } else 2460 } else {
2367 edac_dbg(0, " TOP_MEM2 disabled\n"); 2461 edac_dbg(0, " TOP_MEM2 disabled\n");
2462 }
2463
2464 if (pvt->umc) {
2465 __read_mc_regs_df(pvt);
2466 amd64_read_pci_cfg(pvt->F0, DF_DHAR, &pvt->dhar);
2467
2468 goto skip;
2469 }
2368 2470
2369 amd64_read_pci_cfg(pvt->F3, NBCAP, &pvt->nbcap); 2471 amd64_read_pci_cfg(pvt->F3, NBCAP, &pvt->nbcap);
2370 2472
@@ -2393,8 +2495,6 @@ static void read_mc_regs(struct amd64_pvt *pvt)
2393 dram_dst_node(pvt, range)); 2495 dram_dst_node(pvt, range));
2394 } 2496 }
2395 2497
2396 read_dct_base_mask(pvt);
2397
2398 amd64_read_pci_cfg(pvt->F1, DHAR, &pvt->dhar); 2498 amd64_read_pci_cfg(pvt->F1, DHAR, &pvt->dhar);
2399 amd64_read_dct_pci_cfg(pvt, 0, DBAM0, &pvt->dbam0); 2499 amd64_read_dct_pci_cfg(pvt, 0, DBAM0, &pvt->dbam0);
2400 2500
@@ -2408,20 +2508,14 @@ static void read_mc_regs(struct amd64_pvt *pvt)
2408 amd64_read_dct_pci_cfg(pvt, 1, DCHR0, &pvt->dchr1); 2508 amd64_read_dct_pci_cfg(pvt, 1, DCHR0, &pvt->dchr1);
2409 } 2509 }
2410 2510
2411 pvt->ecc_sym_sz = 4; 2511skip:
2512 read_dct_base_mask(pvt);
2513
2412 determine_memory_type(pvt); 2514 determine_memory_type(pvt);
2413 edac_dbg(1, " DIMM type: %s\n", edac_mem_types[pvt->dram_type]); 2515 edac_dbg(1, " DIMM type: %s\n", edac_mem_types[pvt->dram_type]);
2414 2516
2415 if (pvt->fam >= 0x10) { 2517 determine_ecc_sym_sz(pvt);
2416 amd64_read_pci_cfg(pvt->F3, EXT_NB_MCA_CFG, &tmp);
2417 /* F16h has only DCT0, so no need to read dbam1 */
2418 if (pvt->fam != 0x16)
2419 amd64_read_dct_pci_cfg(pvt, 1, DBAM0, &pvt->dbam1);
2420 2518
2421 /* F10h, revD and later can do x8 ECC too */
2422 if ((pvt->fam > 0x10 || pvt->model > 7) && tmp & BIT(25))
2423 pvt->ecc_sym_sz = 8;
2424 }
2425 dump_misc_regs(pvt); 2519 dump_misc_regs(pvt);
2426} 2520}
2427 2521
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index 4ca7d249f02e..738166393673 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -250,12 +250,23 @@
250/* MSRs */ 250/* MSRs */
251#define MSR_MCGCTL_NBE BIT(4) 251#define MSR_MCGCTL_NBE BIT(4)
252 252
253/* F17h */
254
255/* F0: */
256#define DF_DHAR 0x104
257
253/* UMC CH register offsets */ 258/* UMC CH register offsets */
259#define UMCCH_BASE_ADDR 0x0
260#define UMCCH_ADDR_MASK 0x20
261#define UMCCH_DIMM_CFG 0x80
254#define UMCCH_SDP_CTRL 0x104 262#define UMCCH_SDP_CTRL 0x104
263#define UMCCH_ECC_CTRL 0x14C
255#define UMCCH_UMC_CAP_HI 0xDF4 264#define UMCCH_UMC_CAP_HI 0xDF4
256 265
257/* UMC CH bitfields */ 266/* UMC CH bitfields */
267#define UMC_ECC_CHIPKILL_CAP BIT(31)
258#define UMC_ECC_ENABLED BIT(30) 268#define UMC_ECC_ENABLED BIT(30)
269
259#define UMC_SDP_INIT BIT(31) 270#define UMC_SDP_INIT BIT(31)
260 271
261#define NUM_UMCS 2 272#define NUM_UMCS 2
@@ -302,7 +313,9 @@ struct chip_select {
302}; 313};
303 314
304struct amd64_umc { 315struct amd64_umc {
316 u32 dimm_cfg; /* DIMM Configuration reg */
305 u32 sdp_ctrl; /* SDP Control reg */ 317 u32 sdp_ctrl; /* SDP Control reg */
318 u32 ecc_ctrl; /* DRAM ECC Control reg */
306}; 319};
307 320
308struct amd64_pvt { 321struct amd64_pvt {