Skip to content

Commit 4175242

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp: amd64_edac: Erratum #637 workaround amd64_edac: Factor in CC6 save area amd64_edac: Remove node interleave warning EDAC: Remove debugging output in scrub rate handling
2 parents 45dafe9 + c1ae683 commit 4175242

File tree

3 files changed

+86
-16
lines changed

3 files changed

+86
-16
lines changed

drivers/edac/amd64_edac.c

Lines changed: 78 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,6 @@ static int amd64_get_scrub_rate(struct mem_ctl_info *mci)
211211

212212
scrubval = scrubval & 0x001F;
213213

214-
amd64_debug("pci-read, sdram scrub control value: %d\n", scrubval);
215-
216214
for (i = 0; i < ARRAY_SIZE(scrubrates); i++) {
217215
if (scrubrates[i].scrubval == scrubval) {
218216
retval = scrubrates[i].bandwidth;
@@ -933,32 +931,106 @@ static int k8_early_channel_count(struct amd64_pvt *pvt)
933931
/* On F10h and later ErrAddr is MC4_ADDR[47:1] */
934932
static u64 get_error_address(struct mce *m)
935933
{
934+
struct cpuinfo_x86 *c = &boot_cpu_data;
935+
u64 addr;
936936
u8 start_bit = 1;
937937
u8 end_bit = 47;
938938

939-
if (boot_cpu_data.x86 == 0xf) {
939+
if (c->x86 == 0xf) {
940940
start_bit = 3;
941941
end_bit = 39;
942942
}
943943

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;
945991
}
946992

947993
static void read_dram_base_limit_regs(struct amd64_pvt *pvt, unsigned range)
948994
{
995+
struct cpuinfo_x86 *c = &boot_cpu_data;
949996
int off = range << 3;
950997

951998
amd64_read_pci_cfg(pvt->F1, DRAM_BASE_LO + off, &pvt->ranges[range].base.lo);
952999
amd64_read_pci_cfg(pvt->F1, DRAM_LIMIT_LO + off, &pvt->ranges[range].lim.lo);
9531000

954-
if (boot_cpu_data.x86 == 0xf)
1001+
if (c->x86 == 0xf)
9551002
return;
9561003

9571004
if (!dram_rw(pvt, range))
9581005
return;
9591006

9601007
amd64_read_pci_cfg(pvt->F1, DRAM_BASE_HI + off, &pvt->ranges[range].base.hi);
9611008
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+
}
9621034
}
9631035

9641036
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,
14031475
return -EINVAL;
14041476
}
14051477

1406-
if (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);
1478+
if (intlv_en && (intlv_sel != ((sys_addr >> 12) & intlv_en)))
14101479
return -EINVAL;
1411-
}
14121480

14131481
sys_addr = f1x_swap_interleaved_region(pvt, sys_addr);
14141482

drivers/edac/amd64_edac.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,9 @@
196196

197197
#define DCT_CFG_SEL 0x10C
198198

199+
#define DRAM_LOCAL_NODE_BASE 0x120
200+
#define DRAM_LOCAL_NODE_LIM 0x124
201+
199202
#define DRAM_BASE_HI 0x140
200203
#define DRAM_LIMIT_HI 0x144
201204

drivers/edac/edac_mc_sysfs.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -458,13 +458,13 @@ static ssize_t mci_sdram_scrub_rate_store(struct mem_ctl_info *mci,
458458
return -EINVAL;
459459

460460
new_bw = mci->set_sdram_scrub_rate(mci, bandwidth);
461-
if (new_bw >= 0) {
462-
edac_printk(KERN_DEBUG, EDAC_MC, "Scrub rate set to %d\n", new_bw);
463-
return count;
461+
if (new_bw < 0) {
462+
edac_printk(KERN_WARNING, EDAC_MC,
463+
"Error setting scrub rate to: %lu\n", bandwidth);
464+
return -EINVAL;
464465
}
465466

466-
edac_printk(KERN_DEBUG, EDAC_MC, "Error setting scrub rate to: %lu\n", bandwidth);
467-
return -EINVAL;
467+
return count;
468468
}
469469

470470
/*
@@ -483,7 +483,6 @@ static ssize_t mci_sdram_scrub_rate_show(struct mem_ctl_info *mci, char *data)
483483
return bandwidth;
484484
}
485485

486-
edac_printk(KERN_DEBUG, EDAC_MC, "Read scrub rate: %d\n", bandwidth);
487486
return sprintf(data, "%d\n", bandwidth);
488487
}
489488

0 commit comments

Comments
 (0)