This source file includes following definitions.
- r82600_get_error_info
- r82600_process_error_info
- r82600_check
- ecc_enabled
- r82600_init_csrows
- r82600_probe1
- r82600_init_one
- r82600_remove_one
- r82600_init
- r82600_exit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #include <linux/module.h>
19 #include <linux/init.h>
20 #include <linux/pci.h>
21 #include <linux/pci_ids.h>
22 #include <linux/edac.h>
23 #include "edac_module.h"
24
25 #define EDAC_MOD_STR "r82600_edac"
26
27 #define r82600_printk(level, fmt, arg...) \
28 edac_printk(level, "r82600", fmt, ##arg)
29
30 #define r82600_mc_printk(mci, level, fmt, arg...) \
31 edac_mc_chipset_printk(mci, level, "r82600", fmt, ##arg)
32
33
34
35
36
37
38
39
40
41
42
43 #define R82600_NR_CSROWS 4
44 #define R82600_NR_CHANS 1
45 #define R82600_NR_DIMMS 4
46
47 #define R82600_BRIDGE_ID 0x8200
48
49
50 #define R82600_DRAMC 0x57
51
52
53
54
55
56
57
58
59
60
61
62
63
64 #define R82600_SDRAMC 0x76
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 #define R82600_EAP 0x80
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122 #define R82600_DRBA 0x60
123
124
125
126
127
128
129 struct r82600_error_info {
130 u32 eapr;
131 };
132
133 static bool disable_hardware_scrub;
134
135 static struct edac_pci_ctl_info *r82600_pci;
136
137 static void r82600_get_error_info(struct mem_ctl_info *mci,
138 struct r82600_error_info *info)
139 {
140 struct pci_dev *pdev;
141
142 pdev = to_pci_dev(mci->pdev);
143 pci_read_config_dword(pdev, R82600_EAP, &info->eapr);
144
145 if (info->eapr & BIT(0))
146
147 pci_write_bits32(pdev, R82600_EAP,
148 ((u32) BIT(0) & (u32) BIT(1)),
149 ((u32) BIT(0) & (u32) BIT(1)));
150
151 if (info->eapr & BIT(1))
152
153 pci_write_bits32(pdev, R82600_EAP,
154 ((u32) BIT(0) & (u32) BIT(1)),
155 ((u32) BIT(0) & (u32) BIT(1)));
156 }
157
158 static int r82600_process_error_info(struct mem_ctl_info *mci,
159 struct r82600_error_info *info,
160 int handle_errors)
161 {
162 int error_found;
163 u32 eapaddr, page;
164 u32 syndrome;
165
166 error_found = 0;
167
168
169 eapaddr = ((info->eapr >> 12) & 0x7FFF) << 13;
170
171 syndrome = (info->eapr >> 4) & 0xFF;
172
173
174
175 page = eapaddr >> PAGE_SHIFT;
176
177 if (info->eapr & BIT(0)) {
178 error_found = 1;
179
180 if (handle_errors)
181 edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1,
182 page, 0, syndrome,
183 edac_mc_find_csrow_by_page(mci, page),
184 0, -1,
185 mci->ctl_name, "");
186 }
187
188 if (info->eapr & BIT(1)) {
189 error_found = 1;
190
191 if (handle_errors)
192
193 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1,
194 page, 0, 0,
195 edac_mc_find_csrow_by_page(mci, page),
196 0, -1,
197 mci->ctl_name, "");
198 }
199
200 return error_found;
201 }
202
203 static void r82600_check(struct mem_ctl_info *mci)
204 {
205 struct r82600_error_info info;
206
207 edac_dbg(1, "MC%d\n", mci->mc_idx);
208 r82600_get_error_info(mci, &info);
209 r82600_process_error_info(mci, &info, 1);
210 }
211
212 static inline int ecc_enabled(u8 dramcr)
213 {
214 return dramcr & BIT(5);
215 }
216
217 static void r82600_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev,
218 u8 dramcr)
219 {
220 struct csrow_info *csrow;
221 struct dimm_info *dimm;
222 int index;
223 u8 drbar;
224 u32 row_high_limit, row_high_limit_last;
225 u32 reg_sdram, ecc_on, row_base;
226
227 ecc_on = ecc_enabled(dramcr);
228 reg_sdram = dramcr & BIT(4);
229 row_high_limit_last = 0;
230
231 for (index = 0; index < mci->nr_csrows; index++) {
232 csrow = mci->csrows[index];
233 dimm = csrow->channels[0]->dimm;
234
235
236 pci_read_config_byte(pdev, R82600_DRBA + index, &drbar);
237
238 edac_dbg(1, "Row=%d DRBA = %#0x\n", index, drbar);
239
240 row_high_limit = ((u32) drbar << 24);
241
242
243 edac_dbg(1, "Row=%d, Boundary Address=%#0x, Last = %#0x\n",
244 index, row_high_limit, row_high_limit_last);
245
246
247 if (row_high_limit == row_high_limit_last)
248 continue;
249
250 row_base = row_high_limit_last;
251
252 csrow->first_page = row_base >> PAGE_SHIFT;
253 csrow->last_page = (row_high_limit >> PAGE_SHIFT) - 1;
254
255 dimm->nr_pages = csrow->last_page - csrow->first_page + 1;
256
257
258 dimm->grain = 1 << 14;
259 dimm->mtype = reg_sdram ? MEM_RDDR : MEM_DDR;
260
261 dimm->dtype = DEV_UNKNOWN;
262
263
264 dimm->edac_mode = ecc_on ? EDAC_SECDED : EDAC_NONE;
265 row_high_limit_last = row_high_limit;
266 }
267 }
268
269 static int r82600_probe1(struct pci_dev *pdev, int dev_idx)
270 {
271 struct mem_ctl_info *mci;
272 struct edac_mc_layer layers[2];
273 u8 dramcr;
274 u32 eapr;
275 u32 scrub_disabled;
276 u32 sdram_refresh_rate;
277 struct r82600_error_info discard;
278
279 edac_dbg(0, "\n");
280 pci_read_config_byte(pdev, R82600_DRAMC, &dramcr);
281 pci_read_config_dword(pdev, R82600_EAP, &eapr);
282 scrub_disabled = eapr & BIT(31);
283 sdram_refresh_rate = dramcr & (BIT(0) | BIT(1));
284 edac_dbg(2, "sdram refresh rate = %#0x\n", sdram_refresh_rate);
285 edac_dbg(2, "DRAMC register = %#0x\n", dramcr);
286 layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
287 layers[0].size = R82600_NR_CSROWS;
288 layers[0].is_virt_csrow = true;
289 layers[1].type = EDAC_MC_LAYER_CHANNEL;
290 layers[1].size = R82600_NR_CHANS;
291 layers[1].is_virt_csrow = false;
292 mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers, 0);
293 if (mci == NULL)
294 return -ENOMEM;
295
296 edac_dbg(0, "mci = %p\n", mci);
297 mci->pdev = &pdev->dev;
298 mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_DDR;
299 mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED;
300
301
302
303
304
305
306
307
308 mci->edac_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED;
309
310 if (ecc_enabled(dramcr)) {
311 if (scrub_disabled)
312 edac_dbg(3, "mci = %p - Scrubbing disabled! EAP: %#0x\n",
313 mci, eapr);
314 } else
315 mci->edac_cap = EDAC_FLAG_NONE;
316
317 mci->mod_name = EDAC_MOD_STR;
318 mci->ctl_name = "R82600";
319 mci->dev_name = pci_name(pdev);
320 mci->edac_check = r82600_check;
321 mci->ctl_page_to_phys = NULL;
322 r82600_init_csrows(mci, pdev, dramcr);
323 r82600_get_error_info(mci, &discard);
324
325
326
327
328 if (edac_mc_add_mc(mci)) {
329 edac_dbg(3, "failed edac_mc_add_mc()\n");
330 goto fail;
331 }
332
333
334
335 if (disable_hardware_scrub) {
336 edac_dbg(3, "Disabling Hardware Scrub (scrub on error)\n");
337 pci_write_bits32(pdev, R82600_EAP, BIT(31), BIT(31));
338 }
339
340
341 r82600_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR);
342 if (!r82600_pci) {
343 printk(KERN_WARNING
344 "%s(): Unable to create PCI control\n",
345 __func__);
346 printk(KERN_WARNING
347 "%s(): PCI error report via EDAC not setup\n",
348 __func__);
349 }
350
351 edac_dbg(3, "success\n");
352 return 0;
353
354 fail:
355 edac_mc_free(mci);
356 return -ENODEV;
357 }
358
359
360 static int r82600_init_one(struct pci_dev *pdev,
361 const struct pci_device_id *ent)
362 {
363 edac_dbg(0, "\n");
364
365
366 return r82600_probe1(pdev, ent->driver_data);
367 }
368
369 static void r82600_remove_one(struct pci_dev *pdev)
370 {
371 struct mem_ctl_info *mci;
372
373 edac_dbg(0, "\n");
374
375 if (r82600_pci)
376 edac_pci_release_generic_ctl(r82600_pci);
377
378 if ((mci = edac_mc_del_mc(&pdev->dev)) == NULL)
379 return;
380
381 edac_mc_free(mci);
382 }
383
384 static const struct pci_device_id r82600_pci_tbl[] = {
385 {
386 PCI_DEVICE(PCI_VENDOR_ID_RADISYS, R82600_BRIDGE_ID)
387 },
388 {
389 0,
390 }
391 };
392
393 MODULE_DEVICE_TABLE(pci, r82600_pci_tbl);
394
395 static struct pci_driver r82600_driver = {
396 .name = EDAC_MOD_STR,
397 .probe = r82600_init_one,
398 .remove = r82600_remove_one,
399 .id_table = r82600_pci_tbl,
400 };
401
402 static int __init r82600_init(void)
403 {
404
405 opstate_init();
406
407 return pci_register_driver(&r82600_driver);
408 }
409
410 static void __exit r82600_exit(void)
411 {
412 pci_unregister_driver(&r82600_driver);
413 }
414
415 module_init(r82600_init);
416 module_exit(r82600_exit);
417
418 MODULE_LICENSE("GPL");
419 MODULE_AUTHOR("Tim Small <tim@buttersideup.com> - WPAD Ltd. "
420 "on behalf of EADS Astrium");
421 MODULE_DESCRIPTION("MC support for Radisys 82600 memory controllers");
422
423 module_param(disable_hardware_scrub, bool, 0644);
424 MODULE_PARM_DESC(disable_hardware_scrub,
425 "If set, disable the chipset's automatic scrub for CEs");
426
427 module_param(edac_op_state, int, 0444);
428 MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI");