aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/amd64_edac.h
diff options
context:
space:
mode:
authorAravind Gopalakrishnan <Aravind.Gopalakrishnan@amd.com>2013-08-09 12:54:49 -0400
committerBorislav Petkov <bp@suse.de>2013-08-12 10:00:10 -0400
commit18b94f66f9537003cee30d475d79a57c58f1e1d8 (patch)
tree50250574b9e01bfd86b322635b7ef82a89f06538 /drivers/edac/amd64_edac.h
parent7d64ac6422092adbbdaa279ab32f9d4c90a84558 (diff)
amd64_edac: Add ECC decoding support for newer F15h models
On newer models, support has been included for upto 4 DCT's, however, only DCT0 and DCT3 are currently configured (cf BKDG Section 2.10). Also, the routing DRAM Requests algorithm is different for F15h M30h. Thus it is cleaner to use a brand new function rather than adding quirks to the more generic f1x_match_to_this_node(). Refer to "2.10.5 DRAM Routing Requests" in the BKDG for further info. Tested on Fam15h M30h with ECC turned on using mce_amd_inj facility and verified to be functionally correct. While at it, verify if erratum workarounds for E505 and E637 still hold. From email conversations within AMD, the current status of the errata is: * Erratum 505: fixed in model 0x1, stepping 0x1 and later. * Erratum 637: not fixed. Signed-off-by: Aravind Gopalakrishnan <Aravind.Gopalakrishnan@amd.com> [ Cleanups, corrections ] Signed-off-by: Borislav Petkov <bp@suse.de>
Diffstat (limited to 'drivers/edac/amd64_edac.h')
-rw-r--r--drivers/edac/amd64_edac.h58
1 files changed, 54 insertions, 4 deletions
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index 2c6f113bae2b..8fddad7b3b95 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -170,6 +170,8 @@
170/* 170/*
171 * PCI-defined configuration space registers 171 * PCI-defined configuration space registers
172 */ 172 */
173#define PCI_DEVICE_ID_AMD_15H_M30H_NB_F1 0x141b
174#define PCI_DEVICE_ID_AMD_15H_M30H_NB_F2 0x141c
173#define PCI_DEVICE_ID_AMD_15H_NB_F1 0x1601 175#define PCI_DEVICE_ID_AMD_15H_NB_F1 0x1601
174#define PCI_DEVICE_ID_AMD_15H_NB_F2 0x1602 176#define PCI_DEVICE_ID_AMD_15H_NB_F2 0x1602
175#define PCI_DEVICE_ID_AMD_16H_NB_F1 0x1531 177#define PCI_DEVICE_ID_AMD_16H_NB_F1 0x1531
@@ -181,13 +183,22 @@
181#define DRAM_BASE_LO 0x40 183#define DRAM_BASE_LO 0x40
182#define DRAM_LIMIT_LO 0x44 184#define DRAM_LIMIT_LO 0x44
183 185
184#define dram_intlv_en(pvt, i) ((u8)((pvt->ranges[i].base.lo >> 8) & 0x7)) 186/*
187 * F15 M30h D18F1x2[1C:00]
188 */
189#define DRAM_CONT_BASE 0x200
190#define DRAM_CONT_LIMIT 0x204
191
192/*
193 * F15 M30h D18F1x2[4C:40]
194 */
195#define DRAM_CONT_HIGH_OFF 0x240
196
185#define dram_rw(pvt, i) ((u8)(pvt->ranges[i].base.lo & 0x3)) 197#define dram_rw(pvt, i) ((u8)(pvt->ranges[i].base.lo & 0x3))
186#define dram_intlv_sel(pvt, i) ((u8)((pvt->ranges[i].lim.lo >> 8) & 0x7)) 198#define dram_intlv_sel(pvt, i) ((u8)((pvt->ranges[i].lim.lo >> 8) & 0x7))
187#define dram_dst_node(pvt, i) ((u8)(pvt->ranges[i].lim.lo & 0x7)) 199#define dram_dst_node(pvt, i) ((u8)(pvt->ranges[i].lim.lo & 0x7))
188 200
189#define DHAR 0xf0 201#define DHAR 0xf0
190#define dhar_valid(pvt) ((pvt)->dhar & BIT(0))
191#define dhar_mem_hoist_valid(pvt) ((pvt)->dhar & BIT(1)) 202#define dhar_mem_hoist_valid(pvt) ((pvt)->dhar & BIT(1))
192#define dhar_base(pvt) ((pvt)->dhar & 0xff000000) 203#define dhar_base(pvt) ((pvt)->dhar & 0xff000000)
193#define k8_dhar_offset(pvt) (((pvt)->dhar & 0x0000ff00) << 16) 204#define k8_dhar_offset(pvt) (((pvt)->dhar & 0x0000ff00) << 16)
@@ -234,8 +245,6 @@
234#define DDR3_MODE BIT(8) 245#define DDR3_MODE BIT(8)
235 246
236#define DCT_SEL_LO 0x110 247#define DCT_SEL_LO 0x110
237#define dct_sel_baseaddr(pvt) ((pvt)->dct_sel_lo & 0xFFFFF800)
238#define dct_sel_interleave_addr(pvt) (((pvt)->dct_sel_lo >> 6) & 0x3)
239#define dct_high_range_enabled(pvt) ((pvt)->dct_sel_lo & BIT(0)) 248#define dct_high_range_enabled(pvt) ((pvt)->dct_sel_lo & BIT(0))
240#define dct_interleave_enabled(pvt) ((pvt)->dct_sel_lo & BIT(2)) 249#define dct_interleave_enabled(pvt) ((pvt)->dct_sel_lo & BIT(2))
241 250
@@ -297,6 +306,7 @@ enum amd_families {
297 K8_CPUS = 0, 306 K8_CPUS = 0,
298 F10_CPUS, 307 F10_CPUS,
299 F15_CPUS, 308 F15_CPUS,
309 F15_M30H_CPUS,
300 F16_CPUS, 310 F16_CPUS,
301 NUM_FAMILIES, 311 NUM_FAMILIES,
302}; 312};
@@ -337,6 +347,8 @@ struct amd64_pvt {
337 struct pci_dev *F1, *F2, *F3; 347 struct pci_dev *F1, *F2, *F3;
338 348
339 u16 mc_node_id; /* MC index of this MC node */ 349 u16 mc_node_id; /* MC index of this MC node */
350 u8 fam; /* CPU family */
351 u8 model; /* CPU model */
340 int ext_model; /* extended model value of this node */ 352 int ext_model; /* extended model value of this node */
341 int channel_count; 353 int channel_count;
342 354
@@ -414,6 +426,14 @@ static inline u16 extract_syndrome(u64 status)
414 return ((status >> 47) & 0xff) | ((status >> 16) & 0xff00); 426 return ((status >> 47) & 0xff) | ((status >> 16) & 0xff00);
415} 427}
416 428
429static inline u8 dct_sel_interleave_addr(struct amd64_pvt *pvt)
430{
431 if (pvt->fam == 0x15 && pvt->model >= 0x30)
432 return (((pvt->dct_sel_hi >> 9) & 0x1) << 2) |
433 ((pvt->dct_sel_lo >> 6) & 0x3);
434
435 return ((pvt)->dct_sel_lo >> 6) & 0x3;
436}
417/* 437/*
418 * per-node ECC settings descriptor 438 * per-node ECC settings descriptor
419 */ 439 */
@@ -504,3 +524,33 @@ static inline void enable_caches(void *dummy)
504{ 524{
505 write_cr0(read_cr0() & ~X86_CR0_CD); 525 write_cr0(read_cr0() & ~X86_CR0_CD);
506} 526}
527
528static inline u8 dram_intlv_en(struct amd64_pvt *pvt, unsigned int i)
529{
530 if (pvt->fam == 0x15 && pvt->model >= 0x30) {
531 u32 tmp;
532 amd64_read_pci_cfg(pvt->F1, DRAM_CONT_LIMIT, &tmp);
533 return (u8) tmp & 0xF;
534 }
535 return (u8) (pvt->ranges[i].base.lo >> 8) & 0x7;
536}
537
538static inline u8 dhar_valid(struct amd64_pvt *pvt)
539{
540 if (pvt->fam == 0x15 && pvt->model >= 0x30) {
541 u32 tmp;
542 amd64_read_pci_cfg(pvt->F1, DRAM_CONT_BASE, &tmp);
543 return (tmp >> 1) & BIT(0);
544 }
545 return (pvt)->dhar & BIT(0);
546}
547
548static inline u32 dct_sel_baseaddr(struct amd64_pvt *pvt)
549{
550 if (pvt->fam == 0x15 && pvt->model >= 0x30) {
551 u32 tmp;
552 amd64_read_pci_cfg(pvt->F1, DRAM_CONT_BASE, &tmp);
553 return (tmp >> 11) & 0x1FFF;
554 }
555 return (pvt)->dct_sel_lo & 0xFFFFF800;
556}