xref: /openbmc/linux/drivers/edac/i5100_edac.c (revision 384740dc)
1 /*
2  * Intel 5100 Memory Controllers kernel module
3  *
4  * This file may be distributed under the terms of the
5  * GNU General Public License.
6  *
7  * This module is based on the following document:
8  *
9  * Intel 5100X Chipset Memory Controller Hub (MCH) - Datasheet
10  *      http://download.intel.com/design/chipsets/datashts/318378.pdf
11  *
12  */
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/pci.h>
16 #include <linux/pci_ids.h>
17 #include <linux/slab.h>
18 #include <linux/edac.h>
19 #include <linux/delay.h>
20 #include <linux/mmzone.h>
21 
22 #include "edac_core.h"
23 
24 /* register addresses */
25 
26 /* device 16, func 1 */
27 #define I5100_MC		0x40	/* Memory Control Register */
28 #define I5100_MS		0x44	/* Memory Status Register */
29 #define I5100_SPDDATA		0x48	/* Serial Presence Detect Status Reg */
30 #define I5100_SPDCMD		0x4c	/* Serial Presence Detect Command Reg */
31 #define I5100_TOLM		0x6c	/* Top of Low Memory */
32 #define I5100_MIR0		0x80	/* Memory Interleave Range 0 */
33 #define I5100_MIR1		0x84	/* Memory Interleave Range 1 */
34 #define I5100_AMIR_0		0x8c	/* Adjusted Memory Interleave Range 0 */
35 #define I5100_AMIR_1		0x90	/* Adjusted Memory Interleave Range 1 */
36 #define I5100_FERR_NF_MEM	0xa0	/* MC First Non Fatal Errors */
37 #define		I5100_FERR_NF_MEM_M16ERR_MASK	(1 << 16)
38 #define		I5100_FERR_NF_MEM_M15ERR_MASK	(1 << 15)
39 #define		I5100_FERR_NF_MEM_M14ERR_MASK	(1 << 14)
40 #define		I5100_FERR_NF_MEM_M12ERR_MASK	(1 << 12)
41 #define		I5100_FERR_NF_MEM_M11ERR_MASK	(1 << 11)
42 #define		I5100_FERR_NF_MEM_M10ERR_MASK	(1 << 10)
43 #define		I5100_FERR_NF_MEM_M6ERR_MASK	(1 << 6)
44 #define		I5100_FERR_NF_MEM_M5ERR_MASK	(1 << 5)
45 #define		I5100_FERR_NF_MEM_M4ERR_MASK	(1 << 4)
46 #define		I5100_FERR_NF_MEM_M1ERR_MASK	1
47 #define		I5100_FERR_NF_MEM_ANY_MASK	\
48 			(I5100_FERR_NF_MEM_M16ERR_MASK | \
49 			I5100_FERR_NF_MEM_M15ERR_MASK | \
50 			I5100_FERR_NF_MEM_M14ERR_MASK | \
51 			I5100_FERR_NF_MEM_M12ERR_MASK | \
52 			I5100_FERR_NF_MEM_M11ERR_MASK | \
53 			I5100_FERR_NF_MEM_M10ERR_MASK | \
54 			I5100_FERR_NF_MEM_M6ERR_MASK | \
55 			I5100_FERR_NF_MEM_M5ERR_MASK | \
56 			I5100_FERR_NF_MEM_M4ERR_MASK | \
57 			I5100_FERR_NF_MEM_M1ERR_MASK)
58 #define	I5100_NERR_NF_MEM	0xa4	/* MC Next Non-Fatal Errors */
59 #define I5100_EMASK_MEM		0xa8	/* MC Error Mask Register */
60 
61 /* device 21 and 22, func 0 */
62 #define I5100_MTR_0	0x154	/* Memory Technology Registers 0-3 */
63 #define I5100_DMIR	0x15c	/* DIMM Interleave Range */
64 #define	I5100_VALIDLOG	0x18c	/* Valid Log Markers */
65 #define	I5100_NRECMEMA	0x190	/* Non-Recoverable Memory Error Log Reg A */
66 #define	I5100_NRECMEMB	0x194	/* Non-Recoverable Memory Error Log Reg B */
67 #define	I5100_REDMEMA	0x198	/* Recoverable Memory Data Error Log Reg A */
68 #define	I5100_REDMEMB	0x19c	/* Recoverable Memory Data Error Log Reg B */
69 #define	I5100_RECMEMA	0x1a0	/* Recoverable Memory Error Log Reg A */
70 #define	I5100_RECMEMB	0x1a4	/* Recoverable Memory Error Log Reg B */
71 #define I5100_MTR_4	0x1b0	/* Memory Technology Registers 4,5 */
72 
73 /* bit field accessors */
74 
75 static inline u32 i5100_mc_errdeten(u32 mc)
76 {
77 	return mc >> 5 & 1;
78 }
79 
80 static inline u16 i5100_spddata_rdo(u16 a)
81 {
82 	return a >> 15 & 1;
83 }
84 
85 static inline u16 i5100_spddata_sbe(u16 a)
86 {
87 	return a >> 13 & 1;
88 }
89 
90 static inline u16 i5100_spddata_busy(u16 a)
91 {
92 	return a >> 12 & 1;
93 }
94 
95 static inline u16 i5100_spddata_data(u16 a)
96 {
97 	return a & ((1 << 8) - 1);
98 }
99 
100 static inline u32 i5100_spdcmd_create(u32 dti, u32 ckovrd, u32 sa, u32 ba,
101 				      u32 data, u32 cmd)
102 {
103 	return	((dti & ((1 << 4) - 1))  << 28) |
104 		((ckovrd & 1)            << 27) |
105 		((sa & ((1 << 3) - 1))   << 24) |
106 		((ba & ((1 << 8) - 1))   << 16) |
107 		((data & ((1 << 8) - 1)) <<  8) |
108 		(cmd & 1);
109 }
110 
111 static inline u16 i5100_tolm_tolm(u16 a)
112 {
113 	return a >> 12 & ((1 << 4) - 1);
114 }
115 
116 static inline u16 i5100_mir_limit(u16 a)
117 {
118 	return a >> 4 & ((1 << 12) - 1);
119 }
120 
121 static inline u16 i5100_mir_way1(u16 a)
122 {
123 	return a >> 1 & 1;
124 }
125 
126 static inline u16 i5100_mir_way0(u16 a)
127 {
128 	return a & 1;
129 }
130 
131 static inline u32 i5100_ferr_nf_mem_chan_indx(u32 a)
132 {
133 	return a >> 28 & 1;
134 }
135 
136 static inline u32 i5100_ferr_nf_mem_any(u32 a)
137 {
138 	return a & I5100_FERR_NF_MEM_ANY_MASK;
139 }
140 
141 static inline u32 i5100_nerr_nf_mem_any(u32 a)
142 {
143 	return i5100_ferr_nf_mem_any(a);
144 }
145 
146 static inline u32 i5100_dmir_limit(u32 a)
147 {
148 	return a >> 16 & ((1 << 11) - 1);
149 }
150 
151 static inline u32 i5100_dmir_rank(u32 a, u32 i)
152 {
153 	return a >> (4 * i) & ((1 << 2) - 1);
154 }
155 
156 static inline u16 i5100_mtr_present(u16 a)
157 {
158 	return a >> 10 & 1;
159 }
160 
161 static inline u16 i5100_mtr_ethrottle(u16 a)
162 {
163 	return a >> 9 & 1;
164 }
165 
166 static inline u16 i5100_mtr_width(u16 a)
167 {
168 	return a >> 8 & 1;
169 }
170 
171 static inline u16 i5100_mtr_numbank(u16 a)
172 {
173 	return a >> 6 & 1;
174 }
175 
176 static inline u16 i5100_mtr_numrow(u16 a)
177 {
178 	return a >> 2 & ((1 << 2) - 1);
179 }
180 
181 static inline u16 i5100_mtr_numcol(u16 a)
182 {
183 	return a & ((1 << 2) - 1);
184 }
185 
186 
187 static inline u32 i5100_validlog_redmemvalid(u32 a)
188 {
189 	return a >> 2 & 1;
190 }
191 
192 static inline u32 i5100_validlog_recmemvalid(u32 a)
193 {
194 	return a >> 1 & 1;
195 }
196 
197 static inline u32 i5100_validlog_nrecmemvalid(u32 a)
198 {
199 	return a & 1;
200 }
201 
202 static inline u32 i5100_nrecmema_merr(u32 a)
203 {
204 	return a >> 15 & ((1 << 5) - 1);
205 }
206 
207 static inline u32 i5100_nrecmema_bank(u32 a)
208 {
209 	return a >> 12 & ((1 << 3) - 1);
210 }
211 
212 static inline u32 i5100_nrecmema_rank(u32 a)
213 {
214 	return a >>  8 & ((1 << 3) - 1);
215 }
216 
217 static inline u32 i5100_nrecmema_dm_buf_id(u32 a)
218 {
219 	return a & ((1 << 8) - 1);
220 }
221 
222 static inline u32 i5100_nrecmemb_cas(u32 a)
223 {
224 	return a >> 16 & ((1 << 13) - 1);
225 }
226 
227 static inline u32 i5100_nrecmemb_ras(u32 a)
228 {
229 	return a & ((1 << 16) - 1);
230 }
231 
232 static inline u32 i5100_redmemb_ecc_locator(u32 a)
233 {
234 	return a & ((1 << 18) - 1);
235 }
236 
237 static inline u32 i5100_recmema_merr(u32 a)
238 {
239 	return i5100_nrecmema_merr(a);
240 }
241 
242 static inline u32 i5100_recmema_bank(u32 a)
243 {
244 	return i5100_nrecmema_bank(a);
245 }
246 
247 static inline u32 i5100_recmema_rank(u32 a)
248 {
249 	return i5100_nrecmema_rank(a);
250 }
251 
252 static inline u32 i5100_recmema_dm_buf_id(u32 a)
253 {
254 	return i5100_nrecmema_dm_buf_id(a);
255 }
256 
257 static inline u32 i5100_recmemb_cas(u32 a)
258 {
259 	return i5100_nrecmemb_cas(a);
260 }
261 
262 static inline u32 i5100_recmemb_ras(u32 a)
263 {
264 	return i5100_nrecmemb_ras(a);
265 }
266 
267 /* some generic limits */
268 #define I5100_MAX_RANKS_PER_CTLR	6
269 #define I5100_MAX_CTLRS			2
270 #define I5100_MAX_RANKS_PER_DIMM	4
271 #define I5100_DIMM_ADDR_LINES		(6 - 3)	/* 64 bits / 8 bits per byte */
272 #define I5100_MAX_DIMM_SLOTS_PER_CTLR	4
273 #define I5100_MAX_RANK_INTERLEAVE	4
274 #define I5100_MAX_DMIRS			5
275 
276 struct i5100_priv {
277 	/* ranks on each dimm -- 0 maps to not present -- obtained via SPD */
278 	int dimm_numrank[I5100_MAX_CTLRS][I5100_MAX_DIMM_SLOTS_PER_CTLR];
279 
280 	/*
281 	 * mainboard chip select map -- maps i5100 chip selects to
282 	 * DIMM slot chip selects.  In the case of only 4 ranks per
283 	 * controller, the mapping is fairly obvious but not unique.
284 	 * we map -1 -> NC and assume both controllers use the same
285 	 * map...
286 	 *
287 	 */
288 	int dimm_csmap[I5100_MAX_DIMM_SLOTS_PER_CTLR][I5100_MAX_RANKS_PER_DIMM];
289 
290 	/* memory interleave range */
291 	struct {
292 		u64	 limit;
293 		unsigned way[2];
294 	} mir[I5100_MAX_CTLRS];
295 
296 	/* adjusted memory interleave range register */
297 	unsigned amir[I5100_MAX_CTLRS];
298 
299 	/* dimm interleave range */
300 	struct {
301 		unsigned rank[I5100_MAX_RANK_INTERLEAVE];
302 		u64	 limit;
303 	} dmir[I5100_MAX_CTLRS][I5100_MAX_DMIRS];
304 
305 	/* memory technology registers... */
306 	struct {
307 		unsigned present;	/* 0 or 1 */
308 		unsigned ethrottle;	/* 0 or 1 */
309 		unsigned width;		/* 4 or 8 bits  */
310 		unsigned numbank;	/* 2 or 3 lines */
311 		unsigned numrow;	/* 13 .. 16 lines */
312 		unsigned numcol;	/* 11 .. 12 lines */
313 	} mtr[I5100_MAX_CTLRS][I5100_MAX_RANKS_PER_CTLR];
314 
315 	u64 tolm;		/* top of low memory in bytes */
316 	unsigned ranksperctlr;	/* number of ranks per controller */
317 
318 	struct pci_dev *mc;	/* device 16 func 1 */
319 	struct pci_dev *ch0mm;	/* device 21 func 0 */
320 	struct pci_dev *ch1mm;	/* device 22 func 0 */
321 };
322 
323 /* map a rank/ctlr to a slot number on the mainboard */
324 static int i5100_rank_to_slot(const struct mem_ctl_info *mci,
325 			      int ctlr, int rank)
326 {
327 	const struct i5100_priv *priv = mci->pvt_info;
328 	int i;
329 
330 	for (i = 0; i < I5100_MAX_DIMM_SLOTS_PER_CTLR; i++) {
331 		int j;
332 		const int numrank = priv->dimm_numrank[ctlr][i];
333 
334 		for (j = 0; j < numrank; j++)
335 			if (priv->dimm_csmap[i][j] == rank)
336 				return i * 2 + ctlr;
337 	}
338 
339 	return -1;
340 }
341 
342 static const char *i5100_err_msg(unsigned err)
343 {
344 	static const char *merrs[] = {
345 		"unknown", /* 0 */
346 		"uncorrectable data ECC on replay", /* 1 */
347 		"unknown", /* 2 */
348 		"unknown", /* 3 */
349 		"aliased uncorrectable demand data ECC", /* 4 */
350 		"aliased uncorrectable spare-copy data ECC", /* 5 */
351 		"aliased uncorrectable patrol data ECC", /* 6 */
352 		"unknown", /* 7 */
353 		"unknown", /* 8 */
354 		"unknown", /* 9 */
355 		"non-aliased uncorrectable demand data ECC", /* 10 */
356 		"non-aliased uncorrectable spare-copy data ECC", /* 11 */
357 		"non-aliased uncorrectable patrol data ECC", /* 12 */
358 		"unknown", /* 13 */
359 		"correctable demand data ECC", /* 14 */
360 		"correctable spare-copy data ECC", /* 15 */
361 		"correctable patrol data ECC", /* 16 */
362 		"unknown", /* 17 */
363 		"SPD protocol error", /* 18 */
364 		"unknown", /* 19 */
365 		"spare copy initiated", /* 20 */
366 		"spare copy completed", /* 21 */
367 	};
368 	unsigned i;
369 
370 	for (i = 0; i < ARRAY_SIZE(merrs); i++)
371 		if (1 << i & err)
372 			return merrs[i];
373 
374 	return "none";
375 }
376 
377 /* convert csrow index into a rank (per controller -- 0..5) */
378 static int i5100_csrow_to_rank(const struct mem_ctl_info *mci, int csrow)
379 {
380 	const struct i5100_priv *priv = mci->pvt_info;
381 
382 	return csrow % priv->ranksperctlr;
383 }
384 
385 /* convert csrow index into a controller (0..1) */
386 static int i5100_csrow_to_cntlr(const struct mem_ctl_info *mci, int csrow)
387 {
388 	const struct i5100_priv *priv = mci->pvt_info;
389 
390 	return csrow / priv->ranksperctlr;
391 }
392 
393 static unsigned i5100_rank_to_csrow(const struct mem_ctl_info *mci,
394 				    int ctlr, int rank)
395 {
396 	const struct i5100_priv *priv = mci->pvt_info;
397 
398 	return ctlr * priv->ranksperctlr + rank;
399 }
400 
401 static void i5100_handle_ce(struct mem_ctl_info *mci,
402 			    int ctlr,
403 			    unsigned bank,
404 			    unsigned rank,
405 			    unsigned long syndrome,
406 			    unsigned cas,
407 			    unsigned ras,
408 			    const char *msg)
409 {
410 	const int csrow = i5100_rank_to_csrow(mci, ctlr, rank);
411 
412 	printk(KERN_ERR
413 		"CE ctlr %d, bank %u, rank %u, syndrome 0x%lx, "
414 		"cas %u, ras %u, csrow %u, label \"%s\": %s\n",
415 		ctlr, bank, rank, syndrome, cas, ras,
416 		csrow, mci->csrows[csrow].channels[0].label, msg);
417 
418 	mci->ce_count++;
419 	mci->csrows[csrow].ce_count++;
420 	mci->csrows[csrow].channels[0].ce_count++;
421 }
422 
423 static void i5100_handle_ue(struct mem_ctl_info *mci,
424 			    int ctlr,
425 			    unsigned bank,
426 			    unsigned rank,
427 			    unsigned long syndrome,
428 			    unsigned cas,
429 			    unsigned ras,
430 			    const char *msg)
431 {
432 	const int csrow = i5100_rank_to_csrow(mci, ctlr, rank);
433 
434 	printk(KERN_ERR
435 		"UE ctlr %d, bank %u, rank %u, syndrome 0x%lx, "
436 		"cas %u, ras %u, csrow %u, label \"%s\": %s\n",
437 		ctlr, bank, rank, syndrome, cas, ras,
438 		csrow, mci->csrows[csrow].channels[0].label, msg);
439 
440 	mci->ue_count++;
441 	mci->csrows[csrow].ue_count++;
442 }
443 
444 static void i5100_read_log(struct mem_ctl_info *mci, int ctlr,
445 			   u32 ferr, u32 nerr)
446 {
447 	struct i5100_priv *priv = mci->pvt_info;
448 	struct pci_dev *pdev = (ctlr) ? priv->ch1mm : priv->ch0mm;
449 	u32 dw;
450 	u32 dw2;
451 	unsigned syndrome = 0;
452 	unsigned ecc_loc = 0;
453 	unsigned merr;
454 	unsigned bank;
455 	unsigned rank;
456 	unsigned cas;
457 	unsigned ras;
458 
459 	pci_read_config_dword(pdev, I5100_VALIDLOG, &dw);
460 
461 	if (i5100_validlog_redmemvalid(dw)) {
462 		pci_read_config_dword(pdev, I5100_REDMEMA, &dw2);
463 		syndrome = dw2;
464 		pci_read_config_dword(pdev, I5100_REDMEMB, &dw2);
465 		ecc_loc = i5100_redmemb_ecc_locator(dw2);
466 	}
467 
468 	if (i5100_validlog_recmemvalid(dw)) {
469 		const char *msg;
470 
471 		pci_read_config_dword(pdev, I5100_RECMEMA, &dw2);
472 		merr = i5100_recmema_merr(dw2);
473 		bank = i5100_recmema_bank(dw2);
474 		rank = i5100_recmema_rank(dw2);
475 
476 		pci_read_config_dword(pdev, I5100_RECMEMB, &dw2);
477 		cas = i5100_recmemb_cas(dw2);
478 		ras = i5100_recmemb_ras(dw2);
479 
480 		/* FIXME:  not really sure if this is what merr is...
481 		 */
482 		if (!merr)
483 			msg = i5100_err_msg(ferr);
484 		else
485 			msg = i5100_err_msg(nerr);
486 
487 		i5100_handle_ce(mci, ctlr, bank, rank, syndrome, cas, ras, msg);
488 	}
489 
490 	if (i5100_validlog_nrecmemvalid(dw)) {
491 		const char *msg;
492 
493 		pci_read_config_dword(pdev, I5100_NRECMEMA, &dw2);
494 		merr = i5100_nrecmema_merr(dw2);
495 		bank = i5100_nrecmema_bank(dw2);
496 		rank = i5100_nrecmema_rank(dw2);
497 
498 		pci_read_config_dword(pdev, I5100_NRECMEMB, &dw2);
499 		cas = i5100_nrecmemb_cas(dw2);
500 		ras = i5100_nrecmemb_ras(dw2);
501 
502 		/* FIXME:  not really sure if this is what merr is...
503 		 */
504 		if (!merr)
505 			msg = i5100_err_msg(ferr);
506 		else
507 			msg = i5100_err_msg(nerr);
508 
509 		i5100_handle_ue(mci, ctlr, bank, rank, syndrome, cas, ras, msg);
510 	}
511 
512 	pci_write_config_dword(pdev, I5100_VALIDLOG, dw);
513 }
514 
515 static void i5100_check_error(struct mem_ctl_info *mci)
516 {
517 	struct i5100_priv *priv = mci->pvt_info;
518 	u32 dw;
519 
520 
521 	pci_read_config_dword(priv->mc, I5100_FERR_NF_MEM, &dw);
522 	if (i5100_ferr_nf_mem_any(dw)) {
523 		u32 dw2;
524 
525 		pci_read_config_dword(priv->mc, I5100_NERR_NF_MEM, &dw2);
526 		if (dw2)
527 			pci_write_config_dword(priv->mc, I5100_NERR_NF_MEM,
528 					       dw2);
529 		pci_write_config_dword(priv->mc, I5100_FERR_NF_MEM, dw);
530 
531 		i5100_read_log(mci, i5100_ferr_nf_mem_chan_indx(dw),
532 			       i5100_ferr_nf_mem_any(dw),
533 			       i5100_nerr_nf_mem_any(dw2));
534 	}
535 }
536 
537 static struct pci_dev *pci_get_device_func(unsigned vendor,
538 					   unsigned device,
539 					   unsigned func)
540 {
541 	struct pci_dev *ret = NULL;
542 
543 	while (1) {
544 		ret = pci_get_device(vendor, device, ret);
545 
546 		if (!ret)
547 			break;
548 
549 		if (PCI_FUNC(ret->devfn) == func)
550 			break;
551 	}
552 
553 	return ret;
554 }
555 
556 static unsigned long __devinit i5100_npages(struct mem_ctl_info *mci,
557 					    int csrow)
558 {
559 	struct i5100_priv *priv = mci->pvt_info;
560 	const unsigned ctlr_rank = i5100_csrow_to_rank(mci, csrow);
561 	const unsigned ctlr = i5100_csrow_to_cntlr(mci, csrow);
562 	unsigned addr_lines;
563 
564 	/* dimm present? */
565 	if (!priv->mtr[ctlr][ctlr_rank].present)
566 		return 0ULL;
567 
568 	addr_lines =
569 		I5100_DIMM_ADDR_LINES +
570 		priv->mtr[ctlr][ctlr_rank].numcol +
571 		priv->mtr[ctlr][ctlr_rank].numrow +
572 		priv->mtr[ctlr][ctlr_rank].numbank;
573 
574 	return (unsigned long)
575 		((unsigned long long) (1ULL << addr_lines) / PAGE_SIZE);
576 }
577 
578 static void __devinit i5100_init_mtr(struct mem_ctl_info *mci)
579 {
580 	struct i5100_priv *priv = mci->pvt_info;
581 	struct pci_dev *mms[2] = { priv->ch0mm, priv->ch1mm };
582 	int i;
583 
584 	for (i = 0; i < I5100_MAX_CTLRS; i++) {
585 		int j;
586 		struct pci_dev *pdev = mms[i];
587 
588 		for (j = 0; j < I5100_MAX_RANKS_PER_CTLR; j++) {
589 			const unsigned addr =
590 				(j < 4) ? I5100_MTR_0 + j * 2 :
591 					  I5100_MTR_4 + (j - 4) * 2;
592 			u16 w;
593 
594 			pci_read_config_word(pdev, addr, &w);
595 
596 			priv->mtr[i][j].present = i5100_mtr_present(w);
597 			priv->mtr[i][j].ethrottle = i5100_mtr_ethrottle(w);
598 			priv->mtr[i][j].width = 4 + 4 * i5100_mtr_width(w);
599 			priv->mtr[i][j].numbank = 2 + i5100_mtr_numbank(w);
600 			priv->mtr[i][j].numrow = 13 + i5100_mtr_numrow(w);
601 			priv->mtr[i][j].numcol = 10 + i5100_mtr_numcol(w);
602 		}
603 	}
604 }
605 
606 /*
607  * FIXME: make this into a real i2c adapter (so that dimm-decode
608  * will work)?
609  */
610 static int i5100_read_spd_byte(const struct mem_ctl_info *mci,
611 			       u8 ch, u8 slot, u8 addr, u8 *byte)
612 {
613 	struct i5100_priv *priv = mci->pvt_info;
614 	u16 w;
615 	unsigned long et;
616 
617 	pci_read_config_word(priv->mc, I5100_SPDDATA, &w);
618 	if (i5100_spddata_busy(w))
619 		return -1;
620 
621 	pci_write_config_dword(priv->mc, I5100_SPDCMD,
622 			       i5100_spdcmd_create(0xa, 1, ch * 4 + slot, addr,
623 						   0, 0));
624 
625 	/* wait up to 100ms */
626 	et = jiffies + HZ / 10;
627 	udelay(100);
628 	while (1) {
629 		pci_read_config_word(priv->mc, I5100_SPDDATA, &w);
630 		if (!i5100_spddata_busy(w))
631 			break;
632 		udelay(100);
633 	}
634 
635 	if (!i5100_spddata_rdo(w) || i5100_spddata_sbe(w))
636 		return -1;
637 
638 	*byte = i5100_spddata_data(w);
639 
640 	return 0;
641 }
642 
643 /*
644  * fill dimm chip select map
645  *
646  * FIXME:
647  *   o only valid for 4 ranks per controller
648  *   o not the only way to may chip selects to dimm slots
649  *   o investigate if there is some way to obtain this map from the bios
650  */
651 static void __devinit i5100_init_dimm_csmap(struct mem_ctl_info *mci)
652 {
653 	struct i5100_priv *priv = mci->pvt_info;
654 	int i;
655 
656 	WARN_ON(priv->ranksperctlr != 4);
657 
658 	for (i = 0; i < I5100_MAX_DIMM_SLOTS_PER_CTLR; i++) {
659 		int j;
660 
661 		for (j = 0; j < I5100_MAX_RANKS_PER_DIMM; j++)
662 			priv->dimm_csmap[i][j] = -1; /* default NC */
663 	}
664 
665 	/* only 2 chip selects per slot... */
666 	priv->dimm_csmap[0][0] = 0;
667 	priv->dimm_csmap[0][1] = 3;
668 	priv->dimm_csmap[1][0] = 1;
669 	priv->dimm_csmap[1][1] = 2;
670 	priv->dimm_csmap[2][0] = 2;
671 	priv->dimm_csmap[3][0] = 3;
672 }
673 
674 static void __devinit i5100_init_dimm_layout(struct pci_dev *pdev,
675 					     struct mem_ctl_info *mci)
676 {
677 	struct i5100_priv *priv = mci->pvt_info;
678 	int i;
679 
680 	for (i = 0; i < I5100_MAX_CTLRS; i++) {
681 		int j;
682 
683 		for (j = 0; j < I5100_MAX_DIMM_SLOTS_PER_CTLR; j++) {
684 			u8 rank;
685 
686 			if (i5100_read_spd_byte(mci, i, j, 5, &rank) < 0)
687 				priv->dimm_numrank[i][j] = 0;
688 			else
689 				priv->dimm_numrank[i][j] = (rank & 3) + 1;
690 		}
691 	}
692 
693 	i5100_init_dimm_csmap(mci);
694 }
695 
696 static void __devinit i5100_init_interleaving(struct pci_dev *pdev,
697 					      struct mem_ctl_info *mci)
698 {
699 	u16 w;
700 	u32 dw;
701 	struct i5100_priv *priv = mci->pvt_info;
702 	struct pci_dev *mms[2] = { priv->ch0mm, priv->ch1mm };
703 	int i;
704 
705 	pci_read_config_word(pdev, I5100_TOLM, &w);
706 	priv->tolm = (u64) i5100_tolm_tolm(w) * 256 * 1024 * 1024;
707 
708 	pci_read_config_word(pdev, I5100_MIR0, &w);
709 	priv->mir[0].limit = (u64) i5100_mir_limit(w) << 28;
710 	priv->mir[0].way[1] = i5100_mir_way1(w);
711 	priv->mir[0].way[0] = i5100_mir_way0(w);
712 
713 	pci_read_config_word(pdev, I5100_MIR1, &w);
714 	priv->mir[1].limit = (u64) i5100_mir_limit(w) << 28;
715 	priv->mir[1].way[1] = i5100_mir_way1(w);
716 	priv->mir[1].way[0] = i5100_mir_way0(w);
717 
718 	pci_read_config_word(pdev, I5100_AMIR_0, &w);
719 	priv->amir[0] = w;
720 	pci_read_config_word(pdev, I5100_AMIR_1, &w);
721 	priv->amir[1] = w;
722 
723 	for (i = 0; i < I5100_MAX_CTLRS; i++) {
724 		int j;
725 
726 		for (j = 0; j < 5; j++) {
727 			int k;
728 
729 			pci_read_config_dword(mms[i], I5100_DMIR + j * 4, &dw);
730 
731 			priv->dmir[i][j].limit =
732 				(u64) i5100_dmir_limit(dw) << 28;
733 			for (k = 0; k < I5100_MAX_RANKS_PER_DIMM; k++)
734 				priv->dmir[i][j].rank[k] =
735 					i5100_dmir_rank(dw, k);
736 		}
737 	}
738 
739 	i5100_init_mtr(mci);
740 }
741 
742 static void __devinit i5100_init_csrows(struct mem_ctl_info *mci)
743 {
744 	int i;
745 	unsigned long total_pages = 0UL;
746 	struct i5100_priv *priv = mci->pvt_info;
747 
748 	for (i = 0; i < mci->nr_csrows; i++) {
749 		const unsigned long npages = i5100_npages(mci, i);
750 		const unsigned cntlr = i5100_csrow_to_cntlr(mci, i);
751 		const unsigned rank = i5100_csrow_to_rank(mci, i);
752 
753 		if (!npages)
754 			continue;
755 
756 		/*
757 		 * FIXME: these two are totally bogus -- I don't see how to
758 		 * map them correctly to this structure...
759 		 */
760 		mci->csrows[i].first_page = total_pages;
761 		mci->csrows[i].last_page = total_pages + npages - 1;
762 		mci->csrows[i].page_mask = 0UL;
763 
764 		mci->csrows[i].nr_pages = npages;
765 		mci->csrows[i].grain = 32;
766 		mci->csrows[i].csrow_idx = i;
767 		mci->csrows[i].dtype =
768 			(priv->mtr[cntlr][rank].width == 4) ? DEV_X4 : DEV_X8;
769 		mci->csrows[i].ue_count = 0;
770 		mci->csrows[i].ce_count = 0;
771 		mci->csrows[i].mtype = MEM_RDDR2;
772 		mci->csrows[i].edac_mode = EDAC_SECDED;
773 		mci->csrows[i].mci = mci;
774 		mci->csrows[i].nr_channels = 1;
775 		mci->csrows[i].channels[0].chan_idx = 0;
776 		mci->csrows[i].channels[0].ce_count = 0;
777 		mci->csrows[i].channels[0].csrow = mci->csrows + i;
778 		snprintf(mci->csrows[i].channels[0].label,
779 			 sizeof(mci->csrows[i].channels[0].label),
780 			 "DIMM%u", i5100_rank_to_slot(mci, cntlr, rank));
781 
782 		total_pages += npages;
783 	}
784 }
785 
786 static int __devinit i5100_init_one(struct pci_dev *pdev,
787 				    const struct pci_device_id *id)
788 {
789 	int rc;
790 	struct mem_ctl_info *mci;
791 	struct i5100_priv *priv;
792 	struct pci_dev *ch0mm, *ch1mm;
793 	int ret = 0;
794 	u32 dw;
795 	int ranksperch;
796 
797 	if (PCI_FUNC(pdev->devfn) != 1)
798 		return -ENODEV;
799 
800 	rc = pci_enable_device(pdev);
801 	if (rc < 0) {
802 		ret = rc;
803 		goto bail;
804 	}
805 
806 	/* ECC enabled? */
807 	pci_read_config_dword(pdev, I5100_MC, &dw);
808 	if (!i5100_mc_errdeten(dw)) {
809 		printk(KERN_INFO "i5100_edac: ECC not enabled.\n");
810 		ret = -ENODEV;
811 		goto bail_pdev;
812 	}
813 
814 	/* figure out how many ranks, from strapped state of 48GB_Mode input */
815 	pci_read_config_dword(pdev, I5100_MS, &dw);
816 	ranksperch = !!(dw & (1 << 8)) * 2 + 4;
817 
818 	if (ranksperch != 4) {
819 		/* FIXME: get 6 ranks / controller to work - need hw... */
820 		printk(KERN_INFO "i5100_edac: unsupported configuration.\n");
821 		ret = -ENODEV;
822 		goto bail_pdev;
823 	}
824 
825 	/* enable error reporting... */
826 	pci_read_config_dword(pdev, I5100_EMASK_MEM, &dw);
827 	dw &= ~I5100_FERR_NF_MEM_ANY_MASK;
828 	pci_write_config_dword(pdev, I5100_EMASK_MEM, dw);
829 
830 	/* device 21, func 0, Channel 0 Memory Map, Error Flag/Mask, etc... */
831 	ch0mm = pci_get_device_func(PCI_VENDOR_ID_INTEL,
832 				    PCI_DEVICE_ID_INTEL_5100_21, 0);
833 	if (!ch0mm) {
834 		ret = -ENODEV;
835 		goto bail_pdev;
836 	}
837 
838 	rc = pci_enable_device(ch0mm);
839 	if (rc < 0) {
840 		ret = rc;
841 		goto bail_ch0;
842 	}
843 
844 	/* device 22, func 0, Channel 1 Memory Map, Error Flag/Mask, etc... */
845 	ch1mm = pci_get_device_func(PCI_VENDOR_ID_INTEL,
846 				    PCI_DEVICE_ID_INTEL_5100_22, 0);
847 	if (!ch1mm) {
848 		ret = -ENODEV;
849 		goto bail_disable_ch0;
850 	}
851 
852 	rc = pci_enable_device(ch1mm);
853 	if (rc < 0) {
854 		ret = rc;
855 		goto bail_ch1;
856 	}
857 
858 	mci = edac_mc_alloc(sizeof(*priv), ranksperch * 2, 1, 0);
859 	if (!mci) {
860 		ret = -ENOMEM;
861 		goto bail_disable_ch1;
862 	}
863 
864 	mci->dev = &pdev->dev;
865 
866 	priv = mci->pvt_info;
867 	priv->ranksperctlr = ranksperch;
868 	priv->mc = pdev;
869 	priv->ch0mm = ch0mm;
870 	priv->ch1mm = ch1mm;
871 
872 	i5100_init_dimm_layout(pdev, mci);
873 	i5100_init_interleaving(pdev, mci);
874 
875 	mci->mtype_cap = MEM_FLAG_FB_DDR2;
876 	mci->edac_ctl_cap = EDAC_FLAG_SECDED;
877 	mci->edac_cap = EDAC_FLAG_SECDED;
878 	mci->mod_name = "i5100_edac.c";
879 	mci->mod_ver = "not versioned";
880 	mci->ctl_name = "i5100";
881 	mci->dev_name = pci_name(pdev);
882 	mci->ctl_page_to_phys = NULL;
883 
884 	mci->edac_check = i5100_check_error;
885 
886 	i5100_init_csrows(mci);
887 
888 	/* this strange construction seems to be in every driver, dunno why */
889 	switch (edac_op_state) {
890 	case EDAC_OPSTATE_POLL:
891 	case EDAC_OPSTATE_NMI:
892 		break;
893 	default:
894 		edac_op_state = EDAC_OPSTATE_POLL;
895 		break;
896 	}
897 
898 	if (edac_mc_add_mc(mci)) {
899 		ret = -ENODEV;
900 		goto bail_mc;
901 	}
902 
903 	return ret;
904 
905 bail_mc:
906 	edac_mc_free(mci);
907 
908 bail_disable_ch1:
909 	pci_disable_device(ch1mm);
910 
911 bail_ch1:
912 	pci_dev_put(ch1mm);
913 
914 bail_disable_ch0:
915 	pci_disable_device(ch0mm);
916 
917 bail_ch0:
918 	pci_dev_put(ch0mm);
919 
920 bail_pdev:
921 	pci_disable_device(pdev);
922 
923 bail:
924 	return ret;
925 }
926 
927 static void __devexit i5100_remove_one(struct pci_dev *pdev)
928 {
929 	struct mem_ctl_info *mci;
930 	struct i5100_priv *priv;
931 
932 	mci = edac_mc_del_mc(&pdev->dev);
933 
934 	if (!mci)
935 		return;
936 
937 	priv = mci->pvt_info;
938 	pci_disable_device(pdev);
939 	pci_disable_device(priv->ch0mm);
940 	pci_disable_device(priv->ch1mm);
941 	pci_dev_put(priv->ch0mm);
942 	pci_dev_put(priv->ch1mm);
943 
944 	edac_mc_free(mci);
945 }
946 
947 static const struct pci_device_id i5100_pci_tbl[] __devinitdata = {
948 	/* Device 16, Function 0, Channel 0 Memory Map, Error Flag/Mask, ... */
949 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5100_16) },
950 	{ 0, }
951 };
952 MODULE_DEVICE_TABLE(pci, i5100_pci_tbl);
953 
954 static struct pci_driver i5100_driver = {
955 	.name = KBUILD_BASENAME,
956 	.probe = i5100_init_one,
957 	.remove = __devexit_p(i5100_remove_one),
958 	.id_table = i5100_pci_tbl,
959 };
960 
961 static int __init i5100_init(void)
962 {
963 	int pci_rc;
964 
965 	pci_rc = pci_register_driver(&i5100_driver);
966 
967 	return (pci_rc < 0) ? pci_rc : 0;
968 }
969 
970 static void __exit i5100_exit(void)
971 {
972 	pci_unregister_driver(&i5100_driver);
973 }
974 
975 module_init(i5100_init);
976 module_exit(i5100_exit);
977 
978 MODULE_LICENSE("GPL");
979 MODULE_AUTHOR
980     ("Arthur Jones <ajones@riverbed.com>");
981 MODULE_DESCRIPTION("MC Driver for Intel I5100 memory controllers");
982