diff options
Diffstat (limited to 'drivers/edac/i3000_edac.c')
-rw-r--r-- | drivers/edac/i3000_edac.c | 207 |
1 files changed, 110 insertions, 97 deletions
diff --git a/drivers/edac/i3000_edac.c b/drivers/edac/i3000_edac.c index e895f9f887ab..3ccf3b5eecc3 100644 --- a/drivers/edac/i3000_edac.c +++ b/drivers/edac/i3000_edac.c | |||
@@ -30,105 +30,112 @@ | |||
30 | #define I3000_MCHBAR_MASK 0xffffc000 | 30 | #define I3000_MCHBAR_MASK 0xffffc000 |
31 | #define I3000_MMR_WINDOW_SIZE 16384 | 31 | #define I3000_MMR_WINDOW_SIZE 16384 |
32 | 32 | ||
33 | #define I3000_EDEAP 0x70 /* Extended DRAM Error Address Pointer (8b) | 33 | #define I3000_EDEAP 0x70 /* Extended DRAM Error Address Pointer (8b) |
34 | * | 34 | * |
35 | * 7:1 reserved | 35 | * 7:1 reserved |
36 | * 0 bit 32 of address | 36 | * 0 bit 32 of address |
37 | */ | 37 | */ |
38 | #define I3000_DEAP 0x58 /* DRAM Error Address Pointer (32b) | 38 | #define I3000_DEAP 0x58 /* DRAM Error Address Pointer (32b) |
39 | * | 39 | * |
40 | * 31:7 address | 40 | * 31:7 address |
41 | * 6:1 reserved | 41 | * 6:1 reserved |
42 | * 0 Error channel 0/1 | 42 | * 0 Error channel 0/1 |
43 | */ | 43 | */ |
44 | #define I3000_DEAP_GRAIN (1 << 7) | 44 | #define I3000_DEAP_GRAIN (1 << 7) |
45 | #define I3000_DEAP_PFN(edeap, deap) ((((edeap) & 1) << (32 - PAGE_SHIFT)) | \ | 45 | #define I3000_DEAP_PFN(edeap, deap) ((((edeap) & 1) << (32 - PAGE_SHIFT)) \ |
46 | ((deap) >> PAGE_SHIFT)) | 46 | | ((deap) >> PAGE_SHIFT)) |
47 | #define I3000_DEAP_OFFSET(deap) ((deap) & ~(I3000_DEAP_GRAIN-1) & ~PAGE_MASK) | 47 | #define I3000_DEAP_OFFSET(deap) ((deap) & ~(I3000_DEAP_GRAIN-1) & \ |
48 | ~PAGE_MASK) | ||
48 | #define I3000_DEAP_CHANNEL(deap) ((deap) & 1) | 49 | #define I3000_DEAP_CHANNEL(deap) ((deap) & 1) |
49 | 50 | ||
50 | #define I3000_DERRSYN 0x5c /* DRAM Error Syndrome (8b) | 51 | #define I3000_DERRSYN 0x5c /* DRAM Error Syndrome (8b) |
51 | * | 52 | * |
52 | * 7:0 DRAM ECC Syndrome | 53 | * 7:0 DRAM ECC Syndrome |
53 | */ | 54 | */ |
54 | 55 | ||
55 | #define I3000_ERRSTS 0xc8 /* Error Status Register (16b) | 56 | #define I3000_ERRSTS 0xc8 /* Error Status Register (16b) |
56 | * | 57 | * |
57 | * 15:12 reserved | 58 | * 15:12 reserved |
58 | * 11 MCH Thermal Sensor Event for SMI/SCI/SERR | 59 | * 11 MCH Thermal Sensor Event |
59 | * 10 reserved | 60 | * for SMI/SCI/SERR |
60 | * 9 LOCK to non-DRAM Memory Flag (LCKF) | 61 | * 10 reserved |
61 | * 8 Received Refresh Timeout Flag (RRTOF) | 62 | * 9 LOCK to non-DRAM Memory Flag (LCKF) |
62 | * 7:2 reserved | 63 | * 8 Received Refresh Timeout Flag (RRTOF) |
63 | * 1 Multiple-bit DRAM ECC Error Flag (DMERR) | 64 | * 7:2 reserved |
64 | * 0 Single-bit DRAM ECC Error Flag (DSERR) | 65 | * 1 Multi-bit DRAM ECC Error Flag (DMERR) |
65 | */ | 66 | * 0 Single-bit DRAM ECC Error Flag (DSERR) |
67 | */ | ||
66 | #define I3000_ERRSTS_BITS 0x0b03 /* bits which indicate errors */ | 68 | #define I3000_ERRSTS_BITS 0x0b03 /* bits which indicate errors */ |
67 | #define I3000_ERRSTS_UE 0x0002 | 69 | #define I3000_ERRSTS_UE 0x0002 |
68 | #define I3000_ERRSTS_CE 0x0001 | 70 | #define I3000_ERRSTS_CE 0x0001 |
69 | 71 | ||
70 | #define I3000_ERRCMD 0xca /* Error Command (16b) | 72 | #define I3000_ERRCMD 0xca /* Error Command (16b) |
71 | * | 73 | * |
72 | * 15:12 reserved | 74 | * 15:12 reserved |
73 | * 11 SERR on MCH Thermal Sensor Event (TSESERR) | 75 | * 11 SERR on MCH Thermal Sensor Event |
74 | * 10 reserved | 76 | * (TSESERR) |
75 | * 9 SERR on LOCK to non-DRAM Memory (LCKERR) | 77 | * 10 reserved |
76 | * 8 SERR on DRAM Refresh Timeout (DRTOERR) | 78 | * 9 SERR on LOCK to non-DRAM Memory |
77 | * 7:2 reserved | 79 | * (LCKERR) |
78 | * 1 SERR Multiple-Bit DRAM ECC Error (DMERR) | 80 | * 8 SERR on DRAM Refresh Timeout |
79 | * 0 SERR on Single-Bit ECC Error (DSERR) | 81 | * (DRTOERR) |
80 | */ | 82 | * 7:2 reserved |
83 | * 1 SERR Multi-Bit DRAM ECC Error | ||
84 | * (DMERR) | ||
85 | * 0 SERR on Single-Bit ECC Error | ||
86 | * (DSERR) | ||
87 | */ | ||
81 | 88 | ||
82 | /* Intel MMIO register space - device 0 function 0 - MMR space */ | 89 | /* Intel MMIO register space - device 0 function 0 - MMR space */ |
83 | 90 | ||
84 | #define I3000_DRB_SHIFT 25 /* 32MiB grain */ | 91 | #define I3000_DRB_SHIFT 25 /* 32MiB grain */ |
85 | 92 | ||
86 | #define I3000_C0DRB 0x100 /* Channel 0 DRAM Rank Boundary (8b x 4) | 93 | #define I3000_C0DRB 0x100 /* Channel 0 DRAM Rank Boundary (8b x 4) |
87 | * | 94 | * |
88 | * 7:0 Channel 0 DRAM Rank Boundary Address | 95 | * 7:0 Channel 0 DRAM Rank Boundary Address |
89 | */ | 96 | */ |
90 | #define I3000_C1DRB 0x180 /* Channel 1 DRAM Rank Boundary (8b x 4) | 97 | #define I3000_C1DRB 0x180 /* Channel 1 DRAM Rank Boundary (8b x 4) |
91 | * | 98 | * |
92 | * 7:0 Channel 1 DRAM Rank Boundary Address | 99 | * 7:0 Channel 1 DRAM Rank Boundary Address |
93 | */ | 100 | */ |
94 | 101 | ||
95 | #define I3000_C0DRA 0x108 /* Channel 0 DRAM Rank Attribute (8b x 2) | 102 | #define I3000_C0DRA 0x108 /* Channel 0 DRAM Rank Attribute (8b x 2) |
96 | * | 103 | * |
97 | * 7 reserved | 104 | * 7 reserved |
98 | * 6:4 DRAM odd Rank Attribute | 105 | * 6:4 DRAM odd Rank Attribute |
99 | * 3 reserved | 106 | * 3 reserved |
100 | * 2:0 DRAM even Rank Attribute | 107 | * 2:0 DRAM even Rank Attribute |
101 | * | 108 | * |
102 | * Each attribute defines the page | 109 | * Each attribute defines the page |
103 | * size of the corresponding rank: | 110 | * size of the corresponding rank: |
104 | * 000: unpopulated | 111 | * 000: unpopulated |
105 | * 001: reserved | 112 | * 001: reserved |
106 | * 010: 4 KB | 113 | * 010: 4 KB |
107 | * 011: 8 KB | 114 | * 011: 8 KB |
108 | * 100: 16 KB | 115 | * 100: 16 KB |
109 | * Others: reserved | 116 | * Others: reserved |
110 | */ | 117 | */ |
111 | #define I3000_C1DRA 0x188 /* Channel 1 DRAM Rank Attribute (8b x 2) */ | 118 | #define I3000_C1DRA 0x188 /* Channel 1 DRAM Rank Attribute (8b x 2) */ |
112 | #define ODD_RANK_ATTRIB(dra) (((dra) & 0x70) >> 4) | 119 | #define ODD_RANK_ATTRIB(dra) (((dra) & 0x70) >> 4) |
113 | #define EVEN_RANK_ATTRIB(dra) ((dra) & 0x07) | 120 | #define EVEN_RANK_ATTRIB(dra) ((dra) & 0x07) |
114 | 121 | ||
115 | #define I3000_C0DRC0 0x120 /* DRAM Controller Mode 0 (32b) | 122 | #define I3000_C0DRC0 0x120 /* DRAM Controller Mode 0 (32b) |
116 | * | 123 | * |
117 | * 31:30 reserved | 124 | * 31:30 reserved |
118 | * 29 Initialization Complete (IC) | 125 | * 29 Initialization Complete (IC) |
119 | * 28:11 reserved | 126 | * 28:11 reserved |
120 | * 10:8 Refresh Mode Select (RMS) | 127 | * 10:8 Refresh Mode Select (RMS) |
121 | * 7 reserved | 128 | * 7 reserved |
122 | * 6:4 Mode Select (SMS) | 129 | * 6:4 Mode Select (SMS) |
123 | * 3:2 reserved | 130 | * 3:2 reserved |
124 | * 1:0 DRAM Type (DT) | 131 | * 1:0 DRAM Type (DT) |
125 | */ | 132 | */ |
126 | 133 | ||
127 | #define I3000_C0DRC1 0x124 /* DRAM Controller Mode 1 (32b) | 134 | #define I3000_C0DRC1 0x124 /* DRAM Controller Mode 1 (32b) |
128 | * | 135 | * |
129 | * 31 Enhanced Addressing Enable (ENHADE) | 136 | * 31 Enhanced Addressing Enable (ENHADE) |
130 | * 30:0 reserved | 137 | * 30:0 reserved |
131 | */ | 138 | */ |
132 | 139 | ||
133 | enum i3000p_chips { | 140 | enum i3000p_chips { |
134 | I3000 = 0, | 141 | I3000 = 0, |
@@ -187,7 +194,8 @@ static void i3000_get_error_info(struct mem_ctl_info *mci, | |||
187 | pci_read_config_byte(pdev, I3000_DERRSYN, &info->derrsyn); | 194 | pci_read_config_byte(pdev, I3000_DERRSYN, &info->derrsyn); |
188 | } | 195 | } |
189 | 196 | ||
190 | /* Clear any error bits. | 197 | /* |
198 | * Clear any error bits. | ||
191 | * (Yes, we really clear bits by writing 1 to them.) | 199 | * (Yes, we really clear bits by writing 1 to them.) |
192 | */ | 200 | */ |
193 | pci_write_bits16(pdev, I3000_ERRSTS, I3000_ERRSTS_BITS, | 201 | pci_write_bits16(pdev, I3000_ERRSTS, I3000_ERRSTS_BITS, |
@@ -245,7 +253,8 @@ static int i3000_is_interleaved(const unsigned char *c0dra, | |||
245 | { | 253 | { |
246 | int i; | 254 | int i; |
247 | 255 | ||
248 | /* If the channels aren't populated identically then | 256 | /* |
257 | * If the channels aren't populated identically then | ||
249 | * we're not interleaved. | 258 | * we're not interleaved. |
250 | */ | 259 | */ |
251 | for (i = 0; i < I3000_RANKS_PER_CHANNEL / 2; i++) | 260 | for (i = 0; i < I3000_RANKS_PER_CHANNEL / 2; i++) |
@@ -254,7 +263,8 @@ static int i3000_is_interleaved(const unsigned char *c0dra, | |||
254 | EVEN_RANK_ATTRIB(c1dra[i])) | 263 | EVEN_RANK_ATTRIB(c1dra[i])) |
255 | return 0; | 264 | return 0; |
256 | 265 | ||
257 | /* If the rank boundaries for the two channels are different | 266 | /* |
267 | * If the rank boundaries for the two channels are different | ||
258 | * then we're not interleaved. | 268 | * then we're not interleaved. |
259 | */ | 269 | */ |
260 | for (i = 0; i < I3000_RANKS_PER_CHANNEL; i++) | 270 | for (i = 0; i < I3000_RANKS_PER_CHANNEL; i++) |
@@ -300,7 +310,8 @@ static int i3000_probe1(struct pci_dev *pdev, int dev_idx) | |||
300 | 310 | ||
301 | iounmap(window); | 311 | iounmap(window); |
302 | 312 | ||
303 | /* Figure out how many channels we have. | 313 | /* |
314 | * Figure out how many channels we have. | ||
304 | * | 315 | * |
305 | * If we have what the datasheet calls "asymmetric channels" | 316 | * If we have what the datasheet calls "asymmetric channels" |
306 | * (essentially the same as what was called "virtual single | 317 | * (essentially the same as what was called "virtual single |
@@ -363,7 +374,8 @@ static int i3000_probe1(struct pci_dev *pdev, int dev_idx) | |||
363 | csrow->edac_mode = EDAC_UNKNOWN; | 374 | csrow->edac_mode = EDAC_UNKNOWN; |
364 | } | 375 | } |
365 | 376 | ||
366 | /* Clear any error bits. | 377 | /* |
378 | * Clear any error bits. | ||
367 | * (Yes, we really clear bits by writing 1 to them.) | 379 | * (Yes, we really clear bits by writing 1 to them.) |
368 | */ | 380 | */ |
369 | pci_write_bits16(pdev, I3000_ERRSTS, I3000_ERRSTS_BITS, | 381 | pci_write_bits16(pdev, I3000_ERRSTS, I3000_ERRSTS_BITS, |
@@ -390,7 +402,7 @@ static int i3000_probe1(struct pci_dev *pdev, int dev_idx) | |||
390 | debugf3("MC: %s(): success\n", __func__); | 402 | debugf3("MC: %s(): success\n", __func__); |
391 | return 0; | 403 | return 0; |
392 | 404 | ||
393 | fail: | 405 | fail: |
394 | if (mci) | 406 | if (mci) |
395 | edac_mc_free(mci); | 407 | edac_mc_free(mci); |
396 | 408 | ||
@@ -409,7 +421,7 @@ static int __devinit i3000_init_one(struct pci_dev *pdev, | |||
409 | return -EIO; | 421 | return -EIO; |
410 | 422 | ||
411 | rc = i3000_probe1(pdev, ent->driver_data); | 423 | rc = i3000_probe1(pdev, ent->driver_data); |
412 | if (mci_pdev == NULL) | 424 | if (!mci_pdev) |
413 | mci_pdev = pci_dev_get(pdev); | 425 | mci_pdev = pci_dev_get(pdev); |
414 | 426 | ||
415 | return rc; | 427 | return rc; |
@@ -424,7 +436,8 @@ static void __devexit i3000_remove_one(struct pci_dev *pdev) | |||
424 | if (i3000_pci) | 436 | if (i3000_pci) |
425 | edac_pci_release_generic_ctl(i3000_pci); | 437 | edac_pci_release_generic_ctl(i3000_pci); |
426 | 438 | ||
427 | if ((mci = edac_mc_del_mc(&pdev->dev)) == NULL) | 439 | mci = edac_mc_del_mc(&pdev->dev); |
440 | if (!mci) | ||
428 | return; | 441 | return; |
429 | 442 | ||
430 | edac_mc_free(mci); | 443 | edac_mc_free(mci); |
@@ -457,7 +470,7 @@ static int __init i3000_init(void) | |||
457 | if (pci_rc < 0) | 470 | if (pci_rc < 0) |
458 | goto fail0; | 471 | goto fail0; |
459 | 472 | ||
460 | if (mci_pdev == NULL) { | 473 | if (!mci_pdev) { |
461 | i3000_registered = 0; | 474 | i3000_registered = 0; |
462 | mci_pdev = pci_get_device(PCI_VENDOR_ID_INTEL, | 475 | mci_pdev = pci_get_device(PCI_VENDOR_ID_INTEL, |
463 | PCI_DEVICE_ID_INTEL_3000_HB, NULL); | 476 | PCI_DEVICE_ID_INTEL_3000_HB, NULL); |