diff options
-rw-r--r-- | drivers/edac/amd64_edac.c | 88 | ||||
-rw-r--r-- | drivers/edac/amd64_edac.h | 3 | ||||
-rw-r--r-- | drivers/edac/edac_mc_sysfs.c | 11 |
3 files changed, 86 insertions, 16 deletions
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 31e71c4fc831..9a8bebcf6b17 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c | |||
@@ -211,8 +211,6 @@ static int amd64_get_scrub_rate(struct mem_ctl_info *mci) | |||
211 | 211 | ||
212 | scrubval = scrubval & 0x001F; | 212 | scrubval = scrubval & 0x001F; |
213 | 213 | ||
214 | amd64_debug("pci-read, sdram scrub control value: %d\n", scrubval); | ||
215 | |||
216 | for (i = 0; i < ARRAY_SIZE(scrubrates); i++) { | 214 | for (i = 0; i < ARRAY_SIZE(scrubrates); i++) { |
217 | if (scrubrates[i].scrubval == scrubval) { | 215 | if (scrubrates[i].scrubval == scrubval) { |
218 | retval = scrubrates[i].bandwidth; | 216 | retval = scrubrates[i].bandwidth; |
@@ -933,25 +931,74 @@ static int k8_early_channel_count(struct amd64_pvt *pvt) | |||
933 | /* On F10h and later ErrAddr is MC4_ADDR[47:1] */ | 931 | /* On F10h and later ErrAddr is MC4_ADDR[47:1] */ |
934 | static u64 get_error_address(struct mce *m) | 932 | static u64 get_error_address(struct mce *m) |
935 | { | 933 | { |
934 | struct cpuinfo_x86 *c = &boot_cpu_data; | ||
935 | u64 addr; | ||
936 | u8 start_bit = 1; | 936 | u8 start_bit = 1; |
937 | u8 end_bit = 47; | 937 | u8 end_bit = 47; |
938 | 938 | ||
939 | if (boot_cpu_data.x86 == 0xf) { | 939 | if (c->x86 == 0xf) { |
940 | start_bit = 3; | 940 | start_bit = 3; |
941 | end_bit = 39; | 941 | end_bit = 39; |
942 | } | 942 | } |
943 | 943 | ||
944 | return m->addr & GENMASK(start_bit, end_bit); | 944 | addr = m->addr & GENMASK(start_bit, end_bit); |
945 | |||
946 | /* | ||
947 | * Erratum 637 workaround | ||
948 | */ | ||
949 | if (c->x86 == 0x15) { | ||
950 | struct amd64_pvt *pvt; | ||
951 | u64 cc6_base, tmp_addr; | ||
952 | u32 tmp; | ||
953 | u8 mce_nid, intlv_en; | ||
954 | |||
955 | if ((addr & GENMASK(24, 47)) >> 24 != 0x00fdf7) | ||
956 | return addr; | ||
957 | |||
958 | mce_nid = amd_get_nb_id(m->extcpu); | ||
959 | pvt = mcis[mce_nid]->pvt_info; | ||
960 | |||
961 | amd64_read_pci_cfg(pvt->F1, DRAM_LOCAL_NODE_LIM, &tmp); | ||
962 | intlv_en = tmp >> 21 & 0x7; | ||
963 | |||
964 | /* add [47:27] + 3 trailing bits */ | ||
965 | cc6_base = (tmp & GENMASK(0, 20)) << 3; | ||
966 | |||
967 | /* reverse and add DramIntlvEn */ | ||
968 | cc6_base |= intlv_en ^ 0x7; | ||
969 | |||
970 | /* pin at [47:24] */ | ||
971 | cc6_base <<= 24; | ||
972 | |||
973 | if (!intlv_en) | ||
974 | return cc6_base | (addr & GENMASK(0, 23)); | ||
975 | |||
976 | amd64_read_pci_cfg(pvt->F1, DRAM_LOCAL_NODE_BASE, &tmp); | ||
977 | |||
978 | /* faster log2 */ | ||
979 | tmp_addr = (addr & GENMASK(12, 23)) << __fls(intlv_en + 1); | ||
980 | |||
981 | /* OR DramIntlvSel into bits [14:12] */ | ||
982 | tmp_addr |= (tmp & GENMASK(21, 23)) >> 9; | ||
983 | |||
984 | /* add remaining [11:0] bits from original MC4_ADDR */ | ||
985 | tmp_addr |= addr & GENMASK(0, 11); | ||
986 | |||
987 | return cc6_base | tmp_addr; | ||
988 | } | ||
989 | |||
990 | return addr; | ||
945 | } | 991 | } |
946 | 992 | ||
947 | static void read_dram_base_limit_regs(struct amd64_pvt *pvt, unsigned range) | 993 | static void read_dram_base_limit_regs(struct amd64_pvt *pvt, unsigned range) |
948 | { | 994 | { |
995 | struct cpuinfo_x86 *c = &boot_cpu_data; | ||
949 | int off = range << 3; | 996 | int off = range << 3; |
950 | 997 | ||
951 | amd64_read_pci_cfg(pvt->F1, DRAM_BASE_LO + off, &pvt->ranges[range].base.lo); | 998 | amd64_read_pci_cfg(pvt->F1, DRAM_BASE_LO + off, &pvt->ranges[range].base.lo); |
952 | amd64_read_pci_cfg(pvt->F1, DRAM_LIMIT_LO + off, &pvt->ranges[range].lim.lo); | 999 | amd64_read_pci_cfg(pvt->F1, DRAM_LIMIT_LO + off, &pvt->ranges[range].lim.lo); |
953 | 1000 | ||
954 | if (boot_cpu_data.x86 == 0xf) | 1001 | if (c->x86 == 0xf) |
955 | return; | 1002 | return; |
956 | 1003 | ||
957 | if (!dram_rw(pvt, range)) | 1004 | if (!dram_rw(pvt, range)) |
@@ -959,6 +1006,31 @@ static void read_dram_base_limit_regs(struct amd64_pvt *pvt, unsigned range) | |||
959 | 1006 | ||
960 | amd64_read_pci_cfg(pvt->F1, DRAM_BASE_HI + off, &pvt->ranges[range].base.hi); | 1007 | amd64_read_pci_cfg(pvt->F1, DRAM_BASE_HI + off, &pvt->ranges[range].base.hi); |
961 | amd64_read_pci_cfg(pvt->F1, DRAM_LIMIT_HI + off, &pvt->ranges[range].lim.hi); | 1008 | amd64_read_pci_cfg(pvt->F1, DRAM_LIMIT_HI + off, &pvt->ranges[range].lim.hi); |
1009 | |||
1010 | /* Factor in CC6 save area by reading dst node's limit reg */ | ||
1011 | if (c->x86 == 0x15) { | ||
1012 | struct pci_dev *f1 = NULL; | ||
1013 | u8 nid = dram_dst_node(pvt, range); | ||
1014 | u32 llim; | ||
1015 | |||
1016 | f1 = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0x18 + nid, 1)); | ||
1017 | if (WARN_ON(!f1)) | ||
1018 | return; | ||
1019 | |||
1020 | amd64_read_pci_cfg(f1, DRAM_LOCAL_NODE_LIM, &llim); | ||
1021 | |||
1022 | pvt->ranges[range].lim.lo &= GENMASK(0, 15); | ||
1023 | |||
1024 | /* {[39:27],111b} */ | ||
1025 | pvt->ranges[range].lim.lo |= ((llim & 0x1fff) << 3 | 0x7) << 16; | ||
1026 | |||
1027 | pvt->ranges[range].lim.hi &= GENMASK(0, 7); | ||
1028 | |||
1029 | /* [47:40] */ | ||
1030 | pvt->ranges[range].lim.hi |= llim >> 13; | ||
1031 | |||
1032 | pci_dev_put(f1); | ||
1033 | } | ||
962 | } | 1034 | } |
963 | 1035 | ||
964 | static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr, | 1036 | static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr, |
@@ -1403,12 +1475,8 @@ static int f1x_match_to_this_node(struct amd64_pvt *pvt, unsigned range, | |||
1403 | return -EINVAL; | 1475 | return -EINVAL; |
1404 | } | 1476 | } |
1405 | 1477 | ||
1406 | if (intlv_en && | 1478 | if (intlv_en && (intlv_sel != ((sys_addr >> 12) & intlv_en))) |
1407 | (intlv_sel != ((sys_addr >> 12) & intlv_en))) { | ||
1408 | amd64_warn("Botched intlv bits, en: 0x%x, sel: 0x%x\n", | ||
1409 | intlv_en, intlv_sel); | ||
1410 | return -EINVAL; | 1479 | return -EINVAL; |
1411 | } | ||
1412 | 1480 | ||
1413 | sys_addr = f1x_swap_interleaved_region(pvt, sys_addr); | 1481 | sys_addr = f1x_swap_interleaved_region(pvt, sys_addr); |
1414 | 1482 | ||
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h index 11be36a311eb..9a666cb985b2 100644 --- a/drivers/edac/amd64_edac.h +++ b/drivers/edac/amd64_edac.h | |||
@@ -196,6 +196,9 @@ | |||
196 | 196 | ||
197 | #define DCT_CFG_SEL 0x10C | 197 | #define DCT_CFG_SEL 0x10C |
198 | 198 | ||
199 | #define DRAM_LOCAL_NODE_BASE 0x120 | ||
200 | #define DRAM_LOCAL_NODE_LIM 0x124 | ||
201 | |||
199 | #define DRAM_BASE_HI 0x140 | 202 | #define DRAM_BASE_HI 0x140 |
200 | #define DRAM_LIMIT_HI 0x144 | 203 | #define DRAM_LIMIT_HI 0x144 |
201 | 204 | ||
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index 26343fd46596..29ffa350bfbe 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c | |||
@@ -458,13 +458,13 @@ static ssize_t mci_sdram_scrub_rate_store(struct mem_ctl_info *mci, | |||
458 | return -EINVAL; | 458 | return -EINVAL; |
459 | 459 | ||
460 | new_bw = mci->set_sdram_scrub_rate(mci, bandwidth); | 460 | new_bw = mci->set_sdram_scrub_rate(mci, bandwidth); |
461 | if (new_bw >= 0) { | 461 | if (new_bw < 0) { |
462 | edac_printk(KERN_DEBUG, EDAC_MC, "Scrub rate set to %d\n", new_bw); | 462 | edac_printk(KERN_WARNING, EDAC_MC, |
463 | return count; | 463 | "Error setting scrub rate to: %lu\n", bandwidth); |
464 | return -EINVAL; | ||
464 | } | 465 | } |
465 | 466 | ||
466 | edac_printk(KERN_DEBUG, EDAC_MC, "Error setting scrub rate to: %lu\n", bandwidth); | 467 | return count; |
467 | return -EINVAL; | ||
468 | } | 468 | } |
469 | 469 | ||
470 | /* | 470 | /* |
@@ -483,7 +483,6 @@ static ssize_t mci_sdram_scrub_rate_show(struct mem_ctl_info *mci, char *data) | |||
483 | return bandwidth; | 483 | return bandwidth; |
484 | } | 484 | } |
485 | 485 | ||
486 | edac_printk(KERN_DEBUG, EDAC_MC, "Read scrub rate: %d\n", bandwidth); | ||
487 | return sprintf(data, "%d\n", bandwidth); | 486 | return sprintf(data, "%d\n", bandwidth); |
488 | } | 487 | } |
489 | 488 | ||