0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <linux/module.h>
0019 #include <linux/init.h>
0020 #include <linux/pci.h>
0021 #include <linux/pci_ids.h>
0022 #include <linux/edac.h>
0023 #include "edac_module.h"
0024
0025 #define EDAC_MOD_STR "r82600_edac"
0026
0027 #define r82600_printk(level, fmt, arg...) \
0028 edac_printk(level, "r82600", fmt, ##arg)
0029
0030 #define r82600_mc_printk(mci, level, fmt, arg...) \
0031 edac_mc_chipset_printk(mci, level, "r82600", fmt, ##arg)
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 #define R82600_NR_CSROWS 4
0044 #define R82600_NR_CHANS 1
0045 #define R82600_NR_DIMMS 4
0046
0047 #define R82600_BRIDGE_ID 0x8200
0048
0049
0050 #define R82600_DRAMC 0x57
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064 #define R82600_SDRAMC 0x76
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088 #define R82600_EAP 0x80
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122 #define R82600_DRBA 0x60
0123
0124
0125
0126
0127
0128
0129 struct r82600_error_info {
0130 u32 eapr;
0131 };
0132
0133 static bool disable_hardware_scrub;
0134
0135 static struct edac_pci_ctl_info *r82600_pci;
0136
0137 static void r82600_get_error_info(struct mem_ctl_info *mci,
0138 struct r82600_error_info *info)
0139 {
0140 struct pci_dev *pdev;
0141
0142 pdev = to_pci_dev(mci->pdev);
0143 pci_read_config_dword(pdev, R82600_EAP, &info->eapr);
0144
0145 if (info->eapr & BIT(0))
0146
0147 pci_write_bits32(pdev, R82600_EAP,
0148 ((u32) BIT(0) & (u32) BIT(1)),
0149 ((u32) BIT(0) & (u32) BIT(1)));
0150
0151 if (info->eapr & BIT(1))
0152
0153 pci_write_bits32(pdev, R82600_EAP,
0154 ((u32) BIT(0) & (u32) BIT(1)),
0155 ((u32) BIT(0) & (u32) BIT(1)));
0156 }
0157
0158 static int r82600_process_error_info(struct mem_ctl_info *mci,
0159 struct r82600_error_info *info,
0160 int handle_errors)
0161 {
0162 int error_found;
0163 u32 eapaddr, page;
0164 u32 syndrome;
0165
0166 error_found = 0;
0167
0168
0169 eapaddr = ((info->eapr >> 12) & 0x7FFF) << 13;
0170
0171 syndrome = (info->eapr >> 4) & 0xFF;
0172
0173
0174
0175 page = eapaddr >> PAGE_SHIFT;
0176
0177 if (info->eapr & BIT(0)) {
0178 error_found = 1;
0179
0180 if (handle_errors)
0181 edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1,
0182 page, 0, syndrome,
0183 edac_mc_find_csrow_by_page(mci, page),
0184 0, -1,
0185 mci->ctl_name, "");
0186 }
0187
0188 if (info->eapr & BIT(1)) {
0189 error_found = 1;
0190
0191 if (handle_errors)
0192
0193 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1,
0194 page, 0, 0,
0195 edac_mc_find_csrow_by_page(mci, page),
0196 0, -1,
0197 mci->ctl_name, "");
0198 }
0199
0200 return error_found;
0201 }
0202
0203 static void r82600_check(struct mem_ctl_info *mci)
0204 {
0205 struct r82600_error_info info;
0206
0207 r82600_get_error_info(mci, &info);
0208 r82600_process_error_info(mci, &info, 1);
0209 }
0210
0211 static inline int ecc_enabled(u8 dramcr)
0212 {
0213 return dramcr & BIT(5);
0214 }
0215
0216 static void r82600_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev,
0217 u8 dramcr)
0218 {
0219 struct csrow_info *csrow;
0220 struct dimm_info *dimm;
0221 int index;
0222 u8 drbar;
0223 u32 row_high_limit, row_high_limit_last;
0224 u32 reg_sdram, ecc_on, row_base;
0225
0226 ecc_on = ecc_enabled(dramcr);
0227 reg_sdram = dramcr & BIT(4);
0228 row_high_limit_last = 0;
0229
0230 for (index = 0; index < mci->nr_csrows; index++) {
0231 csrow = mci->csrows[index];
0232 dimm = csrow->channels[0]->dimm;
0233
0234
0235 pci_read_config_byte(pdev, R82600_DRBA + index, &drbar);
0236
0237 edac_dbg(1, "Row=%d DRBA = %#0x\n", index, drbar);
0238
0239 row_high_limit = ((u32) drbar << 24);
0240
0241
0242 edac_dbg(1, "Row=%d, Boundary Address=%#0x, Last = %#0x\n",
0243 index, row_high_limit, row_high_limit_last);
0244
0245
0246 if (row_high_limit == row_high_limit_last)
0247 continue;
0248
0249 row_base = row_high_limit_last;
0250
0251 csrow->first_page = row_base >> PAGE_SHIFT;
0252 csrow->last_page = (row_high_limit >> PAGE_SHIFT) - 1;
0253
0254 dimm->nr_pages = csrow->last_page - csrow->first_page + 1;
0255
0256
0257 dimm->grain = 1 << 14;
0258 dimm->mtype = reg_sdram ? MEM_RDDR : MEM_DDR;
0259
0260 dimm->dtype = DEV_UNKNOWN;
0261
0262
0263 dimm->edac_mode = ecc_on ? EDAC_SECDED : EDAC_NONE;
0264 row_high_limit_last = row_high_limit;
0265 }
0266 }
0267
0268 static int r82600_probe1(struct pci_dev *pdev, int dev_idx)
0269 {
0270 struct mem_ctl_info *mci;
0271 struct edac_mc_layer layers[2];
0272 u8 dramcr;
0273 u32 eapr;
0274 u32 scrub_disabled;
0275 u32 sdram_refresh_rate;
0276 struct r82600_error_info discard;
0277
0278 edac_dbg(0, "\n");
0279 pci_read_config_byte(pdev, R82600_DRAMC, &dramcr);
0280 pci_read_config_dword(pdev, R82600_EAP, &eapr);
0281 scrub_disabled = eapr & BIT(31);
0282 sdram_refresh_rate = dramcr & (BIT(0) | BIT(1));
0283 edac_dbg(2, "sdram refresh rate = %#0x\n", sdram_refresh_rate);
0284 edac_dbg(2, "DRAMC register = %#0x\n", dramcr);
0285 layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
0286 layers[0].size = R82600_NR_CSROWS;
0287 layers[0].is_virt_csrow = true;
0288 layers[1].type = EDAC_MC_LAYER_CHANNEL;
0289 layers[1].size = R82600_NR_CHANS;
0290 layers[1].is_virt_csrow = false;
0291 mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers, 0);
0292 if (mci == NULL)
0293 return -ENOMEM;
0294
0295 edac_dbg(0, "mci = %p\n", mci);
0296 mci->pdev = &pdev->dev;
0297 mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_DDR;
0298 mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED;
0299
0300
0301
0302
0303
0304
0305
0306
0307 mci->edac_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED;
0308
0309 if (ecc_enabled(dramcr)) {
0310 if (scrub_disabled)
0311 edac_dbg(3, "mci = %p - Scrubbing disabled! EAP: %#0x\n",
0312 mci, eapr);
0313 } else
0314 mci->edac_cap = EDAC_FLAG_NONE;
0315
0316 mci->mod_name = EDAC_MOD_STR;
0317 mci->ctl_name = "R82600";
0318 mci->dev_name = pci_name(pdev);
0319 mci->edac_check = r82600_check;
0320 mci->ctl_page_to_phys = NULL;
0321 r82600_init_csrows(mci, pdev, dramcr);
0322 r82600_get_error_info(mci, &discard);
0323
0324
0325
0326
0327 if (edac_mc_add_mc(mci)) {
0328 edac_dbg(3, "failed edac_mc_add_mc()\n");
0329 goto fail;
0330 }
0331
0332
0333
0334 if (disable_hardware_scrub) {
0335 edac_dbg(3, "Disabling Hardware Scrub (scrub on error)\n");
0336 pci_write_bits32(pdev, R82600_EAP, BIT(31), BIT(31));
0337 }
0338
0339
0340 r82600_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR);
0341 if (!r82600_pci) {
0342 printk(KERN_WARNING
0343 "%s(): Unable to create PCI control\n",
0344 __func__);
0345 printk(KERN_WARNING
0346 "%s(): PCI error report via EDAC not setup\n",
0347 __func__);
0348 }
0349
0350 edac_dbg(3, "success\n");
0351 return 0;
0352
0353 fail:
0354 edac_mc_free(mci);
0355 return -ENODEV;
0356 }
0357
0358
0359 static int r82600_init_one(struct pci_dev *pdev,
0360 const struct pci_device_id *ent)
0361 {
0362 edac_dbg(0, "\n");
0363
0364
0365 return r82600_probe1(pdev, ent->driver_data);
0366 }
0367
0368 static void r82600_remove_one(struct pci_dev *pdev)
0369 {
0370 struct mem_ctl_info *mci;
0371
0372 edac_dbg(0, "\n");
0373
0374 if (r82600_pci)
0375 edac_pci_release_generic_ctl(r82600_pci);
0376
0377 if ((mci = edac_mc_del_mc(&pdev->dev)) == NULL)
0378 return;
0379
0380 edac_mc_free(mci);
0381 }
0382
0383 static const struct pci_device_id r82600_pci_tbl[] = {
0384 {
0385 PCI_DEVICE(PCI_VENDOR_ID_RADISYS, R82600_BRIDGE_ID)
0386 },
0387 {
0388 0,
0389 }
0390 };
0391
0392 MODULE_DEVICE_TABLE(pci, r82600_pci_tbl);
0393
0394 static struct pci_driver r82600_driver = {
0395 .name = EDAC_MOD_STR,
0396 .probe = r82600_init_one,
0397 .remove = r82600_remove_one,
0398 .id_table = r82600_pci_tbl,
0399 };
0400
0401 static int __init r82600_init(void)
0402 {
0403
0404 opstate_init();
0405
0406 return pci_register_driver(&r82600_driver);
0407 }
0408
0409 static void __exit r82600_exit(void)
0410 {
0411 pci_unregister_driver(&r82600_driver);
0412 }
0413
0414 module_init(r82600_init);
0415 module_exit(r82600_exit);
0416
0417 MODULE_LICENSE("GPL");
0418 MODULE_AUTHOR("Tim Small <tim@buttersideup.com> - WPAD Ltd. "
0419 "on behalf of EADS Astrium");
0420 MODULE_DESCRIPTION("MC support for Radisys 82600 memory controllers");
0421
0422 module_param(disable_hardware_scrub, bool, 0644);
0423 MODULE_PARM_DESC(disable_hardware_scrub,
0424 "If set, disable the chipset's automatic scrub for CEs");
0425
0426 module_param(edac_op_state, int, 0444);
0427 MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI");