12 #include <linux/module.h>
14 #include <linux/pci.h>
19 #define I3000_REVISION "1.1"
21 #define EDAC_MOD_STR "i3000_edac"
24 #define I3000_RANKS_PER_CHANNEL 4
25 #define I3000_CHANNELS 2
29 #define I3000_MCHBAR 0x44
30 #define I3000_MCHBAR_MASK 0xffffc000
31 #define I3000_MMR_WINDOW_SIZE 16384
33 #define I3000_EDEAP 0x70
38 #define I3000_DEAP 0x58
44 #define I3000_DEAP_GRAIN (1 << 7)
53 static inline unsigned long deap_pfn(
u8 edeap,
u32 deap)
60 static inline unsigned long deap_offset(
u32 deap)
65 static inline int deap_channel(
u32 deap)
70 #define I3000_DERRSYN 0x5c
75 #define I3000_ERRSTS 0xc8
87 #define I3000_ERRSTS_BITS 0x0b03
88 #define I3000_ERRSTS_UE 0x0002
89 #define I3000_ERRSTS_CE 0x0001
91 #define I3000_ERRCMD 0xca
110 #define I3000_DRB_SHIFT 25
112 #define I3000_C0DRB 0x100
116 #define I3000_C1DRB 0x180
121 #define I3000_C0DRA 0x108
137 #define I3000_C1DRA 0x188
139 static inline unsigned char odd_rank_attrib(
unsigned char dra)
141 return (dra & 0x70) >> 4;
144 static inline unsigned char even_rank_attrib(
unsigned char dra)
149 #define I3000_C0DRC0 0x120
161 #define I3000_C0DRC1 0x124
185 .ctl_name =
"i3000"},
188 static struct pci_dev *mci_pdev;
189 static int i3000_registered = 1;
190 static struct edac_pci_ctl_info *i3000_pci;
232 static int i3000_process_error_info(
struct mem_ctl_info *mci,
237 unsigned long pfn,
offset;
239 multi_chan = mci->
csrows[0]->nr_channels - 1;
250 "UE overwrote CE",
"");
255 offset = deap_offset(info->
deap);
256 channel = deap_channel(info->
deap);
268 row, multi_chan ? channel : 0, -1,
279 i3000_get_error_info(mci, &info);
280 i3000_process_error_info(mci, &info, 1);
283 static int i3000_is_interleaved(
const unsigned char *c0dra,
284 const unsigned char *c1dra,
285 const unsigned char *c0drb,
286 const unsigned char *c1drb)
295 if (odd_rank_attrib(c0dra[i]) != odd_rank_attrib(c1dra[i]) ||
296 even_rank_attrib(c0dra[i]) !=
297 even_rank_attrib(c1dra[i]))
305 if (c0drb[i] != c1drb[i])
311 static int i3000_probe1(
struct pci_dev *pdev,
int dev_idx)
317 unsigned long last_cumul_size, nr_pages;
318 int interleaved, nr_channels;
320 unsigned char *c0dra = dra, *c1dra = &dra[I3000_RANKS_PER_CHANNEL / 2];
322 unsigned long mchbar;
356 interleaved = i3000_is_interleaved(c0dra, c1dra, c0drb, c1drb);
357 nr_channels = interleaved ? 2 : 1;
361 layers[0].is_virt_csrow =
true;
363 layers[1].size = nr_channels;
364 layers[1].is_virt_csrow =
false;
393 for (last_cumul_size = i = 0; i < mci->
nr_csrows; i++) {
402 edac_dbg(3,
"MC: (%d) cumul_size 0x%x\n", i, cumul_size);
403 if (cumul_size == last_cumul_size)
408 nr_pages = cumul_size - last_cumul_size;
409 last_cumul_size = cumul_size;
414 dimm->
nr_pages = nr_pages / nr_channels;
431 edac_dbg(3,
"MC: failed edac_mc_add_mc()\n");
439 "%s(): Unable to create PCI control\n",
442 "%s(): PCI error report via EDAC not setup\n",
504 .probe = i3000_init_one,
506 .id_table = i3000_pci_tbl,
509 static int __init i3000_init(
void)
518 pci_rc = pci_register_driver(&i3000_driver);
523 i3000_registered = 0;
527 edac_dbg(0,
"i3000 pci_get_device fail\n");
532 pci_rc = i3000_init_one(mci_pdev, i3000_pci_tbl);
552 static void __exit i3000_exit(
void)
557 if (!i3000_registered) {
558 i3000_remove_one(mci_pdev);
567 MODULE_AUTHOR(
"Akamai Technologies Arthur Ulfeldt/Jason Uhlenkott");