aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/edac/i5100_edac.c110
1 files changed, 55 insertions, 55 deletions
diff --git a/drivers/edac/i5100_edac.c b/drivers/edac/i5100_edac.c
index 22db05a67bfb..b2fbb4567dc6 100644
--- a/drivers/edac/i5100_edac.c
+++ b/drivers/edac/i5100_edac.c
@@ -265,42 +265,42 @@ static inline u32 i5100_recmemb_ras(u32 a)
265} 265}
266 266
267/* some generic limits */ 267/* some generic limits */
268#define I5100_MAX_RANKS_PER_CTLR 6 268#define I5100_MAX_RANKS_PER_CHAN 6
269#define I5100_MAX_CTLRS 2 269#define I5100_CHANNELS 2
270#define I5100_MAX_RANKS_PER_DIMM 4 270#define I5100_MAX_RANKS_PER_DIMM 4
271#define I5100_DIMM_ADDR_LINES (6 - 3) /* 64 bits / 8 bits per byte */ 271#define I5100_DIMM_ADDR_LINES (6 - 3) /* 64 bits / 8 bits per byte */
272#define I5100_MAX_DIMM_SLOTS_PER_CTLR 4 272#define I5100_MAX_DIMM_SLOTS_PER_CHAN 4
273#define I5100_MAX_RANK_INTERLEAVE 4 273#define I5100_MAX_RANK_INTERLEAVE 4
274#define I5100_MAX_DMIRS 5 274#define I5100_MAX_DMIRS 5
275 275
276struct i5100_priv { 276struct i5100_priv {
277 /* ranks on each dimm -- 0 maps to not present -- obtained via SPD */ 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]; 278 int dimm_numrank[I5100_CHANNELS][I5100_MAX_DIMM_SLOTS_PER_CHAN];
279 279
280 /* 280 /*
281 * mainboard chip select map -- maps i5100 chip selects to 281 * mainboard chip select map -- maps i5100 chip selects to
282 * DIMM slot chip selects. In the case of only 4 ranks per 282 * DIMM slot chip selects. In the case of only 4 ranks per
283 * controller, the mapping is fairly obvious but not unique. 283 * channel, the mapping is fairly obvious but not unique.
284 * we map -1 -> NC and assume both controllers use the same 284 * we map -1 -> NC and assume both channels use the same
285 * map... 285 * map...
286 * 286 *
287 */ 287 */
288 int dimm_csmap[I5100_MAX_DIMM_SLOTS_PER_CTLR][I5100_MAX_RANKS_PER_DIMM]; 288 int dimm_csmap[I5100_MAX_DIMM_SLOTS_PER_CHAN][I5100_MAX_RANKS_PER_DIMM];
289 289
290 /* memory interleave range */ 290 /* memory interleave range */
291 struct { 291 struct {
292 u64 limit; 292 u64 limit;
293 unsigned way[2]; 293 unsigned way[2];
294 } mir[I5100_MAX_CTLRS]; 294 } mir[I5100_CHANNELS];
295 295
296 /* adjusted memory interleave range register */ 296 /* adjusted memory interleave range register */
297 unsigned amir[I5100_MAX_CTLRS]; 297 unsigned amir[I5100_CHANNELS];
298 298
299 /* dimm interleave range */ 299 /* dimm interleave range */
300 struct { 300 struct {
301 unsigned rank[I5100_MAX_RANK_INTERLEAVE]; 301 unsigned rank[I5100_MAX_RANK_INTERLEAVE];
302 u64 limit; 302 u64 limit;
303 } dmir[I5100_MAX_CTLRS][I5100_MAX_DMIRS]; 303 } dmir[I5100_CHANNELS][I5100_MAX_DMIRS];
304 304
305 /* memory technology registers... */ 305 /* memory technology registers... */
306 struct { 306 struct {
@@ -310,30 +310,30 @@ struct i5100_priv {
310 unsigned numbank; /* 2 or 3 lines */ 310 unsigned numbank; /* 2 or 3 lines */
311 unsigned numrow; /* 13 .. 16 lines */ 311 unsigned numrow; /* 13 .. 16 lines */
312 unsigned numcol; /* 11 .. 12 lines */ 312 unsigned numcol; /* 11 .. 12 lines */
313 } mtr[I5100_MAX_CTLRS][I5100_MAX_RANKS_PER_CTLR]; 313 } mtr[I5100_CHANNELS][I5100_MAX_RANKS_PER_CHAN];
314 314
315 u64 tolm; /* top of low memory in bytes */ 315 u64 tolm; /* top of low memory in bytes */
316 unsigned ranksperctlr; /* number of ranks per controller */ 316 unsigned ranksperchan; /* number of ranks per channel */
317 317
318 struct pci_dev *mc; /* device 16 func 1 */ 318 struct pci_dev *mc; /* device 16 func 1 */
319 struct pci_dev *ch0mm; /* device 21 func 0 */ 319 struct pci_dev *ch0mm; /* device 21 func 0 */
320 struct pci_dev *ch1mm; /* device 22 func 0 */ 320 struct pci_dev *ch1mm; /* device 22 func 0 */
321}; 321};
322 322
323/* map a rank/ctlr to a slot number on the mainboard */ 323/* map a rank/chan to a slot number on the mainboard */
324static int i5100_rank_to_slot(const struct mem_ctl_info *mci, 324static int i5100_rank_to_slot(const struct mem_ctl_info *mci,
325 int ctlr, int rank) 325 int chan, int rank)
326{ 326{
327 const struct i5100_priv *priv = mci->pvt_info; 327 const struct i5100_priv *priv = mci->pvt_info;
328 int i; 328 int i;
329 329
330 for (i = 0; i < I5100_MAX_DIMM_SLOTS_PER_CTLR; i++) { 330 for (i = 0; i < I5100_MAX_DIMM_SLOTS_PER_CHAN; i++) {
331 int j; 331 int j;
332 const int numrank = priv->dimm_numrank[ctlr][i]; 332 const int numrank = priv->dimm_numrank[chan][i];
333 333
334 for (j = 0; j < numrank; j++) 334 for (j = 0; j < numrank; j++)
335 if (priv->dimm_csmap[i][j] == rank) 335 if (priv->dimm_csmap[i][j] == rank)
336 return i * 2 + ctlr; 336 return i * 2 + chan;
337 } 337 }
338 338
339 return -1; 339 return -1;
@@ -374,32 +374,32 @@ static const char *i5100_err_msg(unsigned err)
374 return "none"; 374 return "none";
375} 375}
376 376
377/* convert csrow index into a rank (per controller -- 0..5) */ 377/* convert csrow index into a rank (per channel -- 0..5) */
378static int i5100_csrow_to_rank(const struct mem_ctl_info *mci, int csrow) 378static int i5100_csrow_to_rank(const struct mem_ctl_info *mci, int csrow)
379{ 379{
380 const struct i5100_priv *priv = mci->pvt_info; 380 const struct i5100_priv *priv = mci->pvt_info;
381 381
382 return csrow % priv->ranksperctlr; 382 return csrow % priv->ranksperchan;
383} 383}
384 384
385/* convert csrow index into a controller (0..1) */ 385/* convert csrow index into a channel (0..1) */
386static int i5100_csrow_to_cntlr(const struct mem_ctl_info *mci, int csrow) 386static int i5100_csrow_to_chan(const struct mem_ctl_info *mci, int csrow)
387{ 387{
388 const struct i5100_priv *priv = mci->pvt_info; 388 const struct i5100_priv *priv = mci->pvt_info;
389 389
390 return csrow / priv->ranksperctlr; 390 return csrow / priv->ranksperchan;
391} 391}
392 392
393static unsigned i5100_rank_to_csrow(const struct mem_ctl_info *mci, 393static unsigned i5100_rank_to_csrow(const struct mem_ctl_info *mci,
394 int ctlr, int rank) 394 int chan, int rank)
395{ 395{
396 const struct i5100_priv *priv = mci->pvt_info; 396 const struct i5100_priv *priv = mci->pvt_info;
397 397
398 return ctlr * priv->ranksperctlr + rank; 398 return chan * priv->ranksperchan + rank;
399} 399}
400 400
401static void i5100_handle_ce(struct mem_ctl_info *mci, 401static void i5100_handle_ce(struct mem_ctl_info *mci,
402 int ctlr, 402 int chan,
403 unsigned bank, 403 unsigned bank,
404 unsigned rank, 404 unsigned rank,
405 unsigned long syndrome, 405 unsigned long syndrome,
@@ -407,12 +407,12 @@ static void i5100_handle_ce(struct mem_ctl_info *mci,
407 unsigned ras, 407 unsigned ras,
408 const char *msg) 408 const char *msg)
409{ 409{
410 const int csrow = i5100_rank_to_csrow(mci, ctlr, rank); 410 const int csrow = i5100_rank_to_csrow(mci, chan, rank);
411 411
412 printk(KERN_ERR 412 printk(KERN_ERR
413 "CE ctlr %d, bank %u, rank %u, syndrome 0x%lx, " 413 "CE chan %d, bank %u, rank %u, syndrome 0x%lx, "
414 "cas %u, ras %u, csrow %u, label \"%s\": %s\n", 414 "cas %u, ras %u, csrow %u, label \"%s\": %s\n",
415 ctlr, bank, rank, syndrome, cas, ras, 415 chan, bank, rank, syndrome, cas, ras,
416 csrow, mci->csrows[csrow].channels[0].label, msg); 416 csrow, mci->csrows[csrow].channels[0].label, msg);
417 417
418 mci->ce_count++; 418 mci->ce_count++;
@@ -421,7 +421,7 @@ static void i5100_handle_ce(struct mem_ctl_info *mci,
421} 421}
422 422
423static void i5100_handle_ue(struct mem_ctl_info *mci, 423static void i5100_handle_ue(struct mem_ctl_info *mci,
424 int ctlr, 424 int chan,
425 unsigned bank, 425 unsigned bank,
426 unsigned rank, 426 unsigned rank,
427 unsigned long syndrome, 427 unsigned long syndrome,
@@ -429,23 +429,23 @@ static void i5100_handle_ue(struct mem_ctl_info *mci,
429 unsigned ras, 429 unsigned ras,
430 const char *msg) 430 const char *msg)
431{ 431{
432 const int csrow = i5100_rank_to_csrow(mci, ctlr, rank); 432 const int csrow = i5100_rank_to_csrow(mci, chan, rank);
433 433
434 printk(KERN_ERR 434 printk(KERN_ERR
435 "UE ctlr %d, bank %u, rank %u, syndrome 0x%lx, " 435 "UE chan %d, bank %u, rank %u, syndrome 0x%lx, "
436 "cas %u, ras %u, csrow %u, label \"%s\": %s\n", 436 "cas %u, ras %u, csrow %u, label \"%s\": %s\n",
437 ctlr, bank, rank, syndrome, cas, ras, 437 chan, bank, rank, syndrome, cas, ras,
438 csrow, mci->csrows[csrow].channels[0].label, msg); 438 csrow, mci->csrows[csrow].channels[0].label, msg);
439 439
440 mci->ue_count++; 440 mci->ue_count++;
441 mci->csrows[csrow].ue_count++; 441 mci->csrows[csrow].ue_count++;
442} 442}
443 443
444static void i5100_read_log(struct mem_ctl_info *mci, int ctlr, 444static void i5100_read_log(struct mem_ctl_info *mci, int chan,
445 u32 ferr, u32 nerr) 445 u32 ferr, u32 nerr)
446{ 446{
447 struct i5100_priv *priv = mci->pvt_info; 447 struct i5100_priv *priv = mci->pvt_info;
448 struct pci_dev *pdev = (ctlr) ? priv->ch1mm : priv->ch0mm; 448 struct pci_dev *pdev = (chan) ? priv->ch1mm : priv->ch0mm;
449 u32 dw; 449 u32 dw;
450 u32 dw2; 450 u32 dw2;
451 unsigned syndrome = 0; 451 unsigned syndrome = 0;
@@ -484,7 +484,7 @@ static void i5100_read_log(struct mem_ctl_info *mci, int ctlr,
484 else 484 else
485 msg = i5100_err_msg(nerr); 485 msg = i5100_err_msg(nerr);
486 486
487 i5100_handle_ce(mci, ctlr, bank, rank, syndrome, cas, ras, msg); 487 i5100_handle_ce(mci, chan, bank, rank, syndrome, cas, ras, msg);
488 } 488 }
489 489
490 if (i5100_validlog_nrecmemvalid(dw)) { 490 if (i5100_validlog_nrecmemvalid(dw)) {
@@ -506,7 +506,7 @@ static void i5100_read_log(struct mem_ctl_info *mci, int ctlr,
506 else 506 else
507 msg = i5100_err_msg(nerr); 507 msg = i5100_err_msg(nerr);
508 508
509 i5100_handle_ue(mci, ctlr, bank, rank, syndrome, cas, ras, msg); 509 i5100_handle_ue(mci, chan, bank, rank, syndrome, cas, ras, msg);
510 } 510 }
511 511
512 pci_write_config_dword(pdev, I5100_VALIDLOG, dw); 512 pci_write_config_dword(pdev, I5100_VALIDLOG, dw);
@@ -557,19 +557,19 @@ static unsigned long __devinit i5100_npages(struct mem_ctl_info *mci,
557 int csrow) 557 int csrow)
558{ 558{
559 struct i5100_priv *priv = mci->pvt_info; 559 struct i5100_priv *priv = mci->pvt_info;
560 const unsigned ctlr_rank = i5100_csrow_to_rank(mci, csrow); 560 const unsigned chan_rank = i5100_csrow_to_rank(mci, csrow);
561 const unsigned ctlr = i5100_csrow_to_cntlr(mci, csrow); 561 const unsigned chan = i5100_csrow_to_chan(mci, csrow);
562 unsigned addr_lines; 562 unsigned addr_lines;
563 563
564 /* dimm present? */ 564 /* dimm present? */
565 if (!priv->mtr[ctlr][ctlr_rank].present) 565 if (!priv->mtr[chan][chan_rank].present)
566 return 0ULL; 566 return 0ULL;
567 567
568 addr_lines = 568 addr_lines =
569 I5100_DIMM_ADDR_LINES + 569 I5100_DIMM_ADDR_LINES +
570 priv->mtr[ctlr][ctlr_rank].numcol + 570 priv->mtr[chan][chan_rank].numcol +
571 priv->mtr[ctlr][ctlr_rank].numrow + 571 priv->mtr[chan][chan_rank].numrow +
572 priv->mtr[ctlr][ctlr_rank].numbank; 572 priv->mtr[chan][chan_rank].numbank;
573 573
574 return (unsigned long) 574 return (unsigned long)
575 ((unsigned long long) (1ULL << addr_lines) / PAGE_SIZE); 575 ((unsigned long long) (1ULL << addr_lines) / PAGE_SIZE);
@@ -581,11 +581,11 @@ static void __devinit i5100_init_mtr(struct mem_ctl_info *mci)
581 struct pci_dev *mms[2] = { priv->ch0mm, priv->ch1mm }; 581 struct pci_dev *mms[2] = { priv->ch0mm, priv->ch1mm };
582 int i; 582 int i;
583 583
584 for (i = 0; i < I5100_MAX_CTLRS; i++) { 584 for (i = 0; i < I5100_CHANNELS; i++) {
585 int j; 585 int j;
586 struct pci_dev *pdev = mms[i]; 586 struct pci_dev *pdev = mms[i];
587 587
588 for (j = 0; j < I5100_MAX_RANKS_PER_CTLR; j++) { 588 for (j = 0; j < I5100_MAX_RANKS_PER_CHAN; j++) {
589 const unsigned addr = 589 const unsigned addr =
590 (j < 4) ? I5100_MTR_0 + j * 2 : 590 (j < 4) ? I5100_MTR_0 + j * 2 :
591 I5100_MTR_4 + (j - 4) * 2; 591 I5100_MTR_4 + (j - 4) * 2;
@@ -644,7 +644,7 @@ static int i5100_read_spd_byte(const struct mem_ctl_info *mci,
644 * fill dimm chip select map 644 * fill dimm chip select map
645 * 645 *
646 * FIXME: 646 * FIXME:
647 * o only valid for 4 ranks per controller 647 * o only valid for 4 ranks per channel
648 * o not the only way to may chip selects to dimm slots 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 649 * o investigate if there is some way to obtain this map from the bios
650 */ 650 */
@@ -653,9 +653,9 @@ static void __devinit i5100_init_dimm_csmap(struct mem_ctl_info *mci)
653 struct i5100_priv *priv = mci->pvt_info; 653 struct i5100_priv *priv = mci->pvt_info;
654 int i; 654 int i;
655 655
656 WARN_ON(priv->ranksperctlr != 4); 656 WARN_ON(priv->ranksperchan != 4);
657 657
658 for (i = 0; i < I5100_MAX_DIMM_SLOTS_PER_CTLR; i++) { 658 for (i = 0; i < I5100_MAX_DIMM_SLOTS_PER_CHAN; i++) {
659 int j; 659 int j;
660 660
661 for (j = 0; j < I5100_MAX_RANKS_PER_DIMM; j++) 661 for (j = 0; j < I5100_MAX_RANKS_PER_DIMM; j++)
@@ -677,10 +677,10 @@ static void __devinit i5100_init_dimm_layout(struct pci_dev *pdev,
677 struct i5100_priv *priv = mci->pvt_info; 677 struct i5100_priv *priv = mci->pvt_info;
678 int i; 678 int i;
679 679
680 for (i = 0; i < I5100_MAX_CTLRS; i++) { 680 for (i = 0; i < I5100_CHANNELS; i++) {
681 int j; 681 int j;
682 682
683 for (j = 0; j < I5100_MAX_DIMM_SLOTS_PER_CTLR; j++) { 683 for (j = 0; j < I5100_MAX_DIMM_SLOTS_PER_CHAN; j++) {
684 u8 rank; 684 u8 rank;
685 685
686 if (i5100_read_spd_byte(mci, i, j, 5, &rank) < 0) 686 if (i5100_read_spd_byte(mci, i, j, 5, &rank) < 0)
@@ -720,7 +720,7 @@ static void __devinit i5100_init_interleaving(struct pci_dev *pdev,
720 pci_read_config_word(pdev, I5100_AMIR_1, &w); 720 pci_read_config_word(pdev, I5100_AMIR_1, &w);
721 priv->amir[1] = w; 721 priv->amir[1] = w;
722 722
723 for (i = 0; i < I5100_MAX_CTLRS; i++) { 723 for (i = 0; i < I5100_CHANNELS; i++) {
724 int j; 724 int j;
725 725
726 for (j = 0; j < 5; j++) { 726 for (j = 0; j < 5; j++) {
@@ -747,7 +747,7 @@ static void __devinit i5100_init_csrows(struct mem_ctl_info *mci)
747 747
748 for (i = 0; i < mci->nr_csrows; i++) { 748 for (i = 0; i < mci->nr_csrows; i++) {
749 const unsigned long npages = i5100_npages(mci, i); 749 const unsigned long npages = i5100_npages(mci, i);
750 const unsigned cntlr = i5100_csrow_to_cntlr(mci, i); 750 const unsigned chan = i5100_csrow_to_chan(mci, i);
751 const unsigned rank = i5100_csrow_to_rank(mci, i); 751 const unsigned rank = i5100_csrow_to_rank(mci, i);
752 752
753 if (!npages) 753 if (!npages)
@@ -765,7 +765,7 @@ static void __devinit i5100_init_csrows(struct mem_ctl_info *mci)
765 mci->csrows[i].grain = 32; 765 mci->csrows[i].grain = 32;
766 mci->csrows[i].csrow_idx = i; 766 mci->csrows[i].csrow_idx = i;
767 mci->csrows[i].dtype = 767 mci->csrows[i].dtype =
768 (priv->mtr[cntlr][rank].width == 4) ? DEV_X4 : DEV_X8; 768 (priv->mtr[chan][rank].width == 4) ? DEV_X4 : DEV_X8;
769 mci->csrows[i].ue_count = 0; 769 mci->csrows[i].ue_count = 0;
770 mci->csrows[i].ce_count = 0; 770 mci->csrows[i].ce_count = 0;
771 mci->csrows[i].mtype = MEM_RDDR2; 771 mci->csrows[i].mtype = MEM_RDDR2;
@@ -777,7 +777,7 @@ static void __devinit i5100_init_csrows(struct mem_ctl_info *mci)
777 mci->csrows[i].channels[0].csrow = mci->csrows + i; 777 mci->csrows[i].channels[0].csrow = mci->csrows + i;
778 snprintf(mci->csrows[i].channels[0].label, 778 snprintf(mci->csrows[i].channels[0].label,
779 sizeof(mci->csrows[i].channels[0].label), 779 sizeof(mci->csrows[i].channels[0].label),
780 "DIMM%u", i5100_rank_to_slot(mci, cntlr, rank)); 780 "DIMM%u", i5100_rank_to_slot(mci, chan, rank));
781 781
782 total_pages += npages; 782 total_pages += npages;
783 } 783 }
@@ -816,7 +816,7 @@ static int __devinit i5100_init_one(struct pci_dev *pdev,
816 ranksperch = !!(dw & (1 << 8)) * 2 + 4; 816 ranksperch = !!(dw & (1 << 8)) * 2 + 4;
817 817
818 if (ranksperch != 4) { 818 if (ranksperch != 4) {
819 /* FIXME: get 6 ranks / controller to work - need hw... */ 819 /* FIXME: get 6 ranks / channel to work - need hw... */
820 printk(KERN_INFO "i5100_edac: unsupported configuration.\n"); 820 printk(KERN_INFO "i5100_edac: unsupported configuration.\n");
821 ret = -ENODEV; 821 ret = -ENODEV;
822 goto bail_pdev; 822 goto bail_pdev;
@@ -864,7 +864,7 @@ static int __devinit i5100_init_one(struct pci_dev *pdev,
864 mci->dev = &pdev->dev; 864 mci->dev = &pdev->dev;
865 865
866 priv = mci->pvt_info; 866 priv = mci->pvt_info;
867 priv->ranksperctlr = ranksperch; 867 priv->ranksperchan = ranksperch;
868 priv->mc = pdev; 868 priv->mc = pdev;
869 priv->ch0mm = ch0mm; 869 priv->ch0mm = ch0mm;
870 priv->ch1mm = ch1mm; 870 priv->ch1mm = ch1mm;