aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/i5100_edac.c
diff options
context:
space:
mode:
authorNils Carlson <nils.carlson@ludd.ltu.se>2009-12-15 19:47:42 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-16 10:20:12 -0500
commitbbead2104e912571c3afb2aafe5ece1b446b56d9 (patch)
tree089512d5bb9738dce074d51dfc260fad7d51a37e /drivers/edac/i5100_edac.c
parent295439f2a341f2742fa11d143eda0940c5d4acfa (diff)
edac: i5100 add 6 ranks per channel
Add support for 6 ranks per channel to the i5100 chipset. I have tested the patch as far as possible with correctible errors and things appear good. The DIMM mapping is correct for our board, but boards may differ. Signed-off-by: Nils Carlson <nils.carlson@ludd.ltu.se> Acked-by: Arthur Jones <ajones@riverbed.com> Signed-off-by: Doug Thompson <dougthompson@xmission.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/edac/i5100_edac.c')
-rw-r--r--drivers/edac/i5100_edac.c36
1 files changed, 20 insertions, 16 deletions
diff --git a/drivers/edac/i5100_edac.c b/drivers/edac/i5100_edac.c
index 9a933180b434..7785d8ffa404 100644
--- a/drivers/edac/i5100_edac.c
+++ b/drivers/edac/i5100_edac.c
@@ -9,6 +9,11 @@
9 * Intel 5100X Chipset Memory Controller Hub (MCH) - Datasheet 9 * Intel 5100X Chipset Memory Controller Hub (MCH) - Datasheet
10 * http://download.intel.com/design/chipsets/datashts/318378.pdf 10 * http://download.intel.com/design/chipsets/datashts/318378.pdf
11 * 11 *
12 * The intel 5100 has two independent channels. EDAC core currently
13 * can not reflect this configuration so instead the chip-select
14 * rows for each respective channel are layed out one after another,
15 * the first half belonging to channel 0, the second half belonging
16 * to channel 1.
12 */ 17 */
13#include <linux/module.h> 18#include <linux/module.h>
14#include <linux/init.h> 19#include <linux/init.h>
@@ -734,7 +739,6 @@ static int i5100_read_spd_byte(const struct mem_ctl_info *mci,
734 * fill dimm chip select map 739 * fill dimm chip select map
735 * 740 *
736 * FIXME: 741 * FIXME:
737 * o only valid for 4 ranks per channel
738 * o not the only way to may chip selects to dimm slots 742 * o not the only way to may chip selects to dimm slots
739 * o investigate if there is some way to obtain this map from the bios 743 * o investigate if there is some way to obtain this map from the bios
740 */ 744 */
@@ -743,8 +747,6 @@ static void __devinit i5100_init_dimm_csmap(struct mem_ctl_info *mci)
743 struct i5100_priv *priv = mci->pvt_info; 747 struct i5100_priv *priv = mci->pvt_info;
744 int i; 748 int i;
745 749
746 WARN_ON(priv->ranksperchan != 4);
747
748 for (i = 0; i < I5100_MAX_DIMM_SLOTS_PER_CHAN; i++) { 750 for (i = 0; i < I5100_MAX_DIMM_SLOTS_PER_CHAN; i++) {
749 int j; 751 int j;
750 752
@@ -753,12 +755,21 @@ static void __devinit i5100_init_dimm_csmap(struct mem_ctl_info *mci)
753 } 755 }
754 756
755 /* only 2 chip selects per slot... */ 757 /* only 2 chip selects per slot... */
756 priv->dimm_csmap[0][0] = 0; 758 if (priv->ranksperchan == 4) {
757 priv->dimm_csmap[0][1] = 3; 759 priv->dimm_csmap[0][0] = 0;
758 priv->dimm_csmap[1][0] = 1; 760 priv->dimm_csmap[0][1] = 3;
759 priv->dimm_csmap[1][1] = 2; 761 priv->dimm_csmap[1][0] = 1;
760 priv->dimm_csmap[2][0] = 2; 762 priv->dimm_csmap[1][1] = 2;
761 priv->dimm_csmap[3][0] = 3; 763 priv->dimm_csmap[2][0] = 2;
764 priv->dimm_csmap[3][0] = 3;
765 } else {
766 priv->dimm_csmap[0][0] = 0;
767 priv->dimm_csmap[0][1] = 1;
768 priv->dimm_csmap[1][0] = 2;
769 priv->dimm_csmap[1][1] = 3;
770 priv->dimm_csmap[2][0] = 4;
771 priv->dimm_csmap[2][1] = 5;
772 }
762} 773}
763 774
764static void __devinit i5100_init_dimm_layout(struct pci_dev *pdev, 775static void __devinit i5100_init_dimm_layout(struct pci_dev *pdev,
@@ -905,13 +916,6 @@ static int __devinit i5100_init_one(struct pci_dev *pdev,
905 pci_read_config_dword(pdev, I5100_MS, &dw); 916 pci_read_config_dword(pdev, I5100_MS, &dw);
906 ranksperch = !!(dw & (1 << 8)) * 2 + 4; 917 ranksperch = !!(dw & (1 << 8)) * 2 + 4;
907 918
908 if (ranksperch != 4) {
909 /* FIXME: get 6 ranks / channel to work - need hw... */
910 printk(KERN_INFO "i5100_edac: unsupported configuration.\n");
911 ret = -ENODEV;
912 goto bail_pdev;
913 }
914
915 /* enable error reporting... */ 919 /* enable error reporting... */
916 pci_read_config_dword(pdev, I5100_EMASK_MEM, &dw); 920 pci_read_config_dword(pdev, I5100_EMASK_MEM, &dw);
917 dw &= ~I5100_FERR_NF_MEM_ANY_MASK; 921 dw &= ~I5100_FERR_NF_MEM_ANY_MASK;