2  * Intel 82860 Memory Controller kernel module
 
   3  * (C) 2005 Red Hat (http://www.redhat.com)
 
   4  * This file may be distributed under the terms of the
 
   5  * GNU General Public License.
 
   7  * Written by Ben Woodard <woodard@redhat.com>
 
   8  * shamelessly copied from and based upon the edac_i82875 driver
 
   9  * by Thayne Harbaugh of Linux Networx. (http://lnxi.com)
 
  12 #include <linux/module.h>
 
  13 #include <linux/init.h>
 
  14 #include <linux/pci.h>
 
  15 #include <linux/pci_ids.h>
 
  16 #include <linux/slab.h>
 
  17 #include <linux/edac.h>
 
  18 #include "edac_core.h"
 
  20 #define  I82860_REVISION " Ver: 2.0.2 " __DATE__
 
  21 #define EDAC_MOD_STR    "i82860_edac"
 
  23 #define i82860_printk(level, fmt, arg...) \
 
  24         edac_printk(level, "i82860", fmt, ##arg)
 
  26 #define i82860_mc_printk(mci, level, fmt, arg...) \
 
  27         edac_mc_chipset_printk(mci, level, "i82860", fmt, ##arg)
 
  29 #ifndef PCI_DEVICE_ID_INTEL_82860_0
 
  30 #define PCI_DEVICE_ID_INTEL_82860_0     0x2531
 
  31 #endif                          /* PCI_DEVICE_ID_INTEL_82860_0 */
 
  33 #define I82860_MCHCFG 0x50
 
  34 #define I82860_GBA 0x60
 
  35 #define I82860_GBA_MASK 0x7FF
 
  36 #define I82860_GBA_SHIFT 24
 
  37 #define I82860_ERRSTS 0xC8
 
  38 #define I82860_EAP 0xE4
 
  39 #define I82860_DERRCTL_STS 0xE2
 
  45 struct i82860_dev_info {
 
  49 struct i82860_error_info {
 
  56 static const struct i82860_dev_info i82860_devs[] = {
 
  58                 .ctl_name = "i82860"},
 
  61 static struct pci_dev *mci_pdev;        /* init dev: in case that AGP code
 
  62                                          * has already registered driver
 
  64 static struct edac_pci_ctl_info *i82860_pci;
 
  66 static void i82860_get_error_info(struct mem_ctl_info *mci,
 
  67                                 struct i82860_error_info *info)
 
  71         pdev = to_pci_dev(mci->dev);
 
  74          * This is a mess because there is no atomic way to read all the
 
  75          * registers at once and the registers can transition from CE being
 
  78         pci_read_config_word(pdev, I82860_ERRSTS, &info->errsts);
 
  79         pci_read_config_dword(pdev, I82860_EAP, &info->eap);
 
  80         pci_read_config_word(pdev, I82860_DERRCTL_STS, &info->derrsyn);
 
  81         pci_read_config_word(pdev, I82860_ERRSTS, &info->errsts2);
 
  83         pci_write_bits16(pdev, I82860_ERRSTS, 0x0003, 0x0003);
 
  86          * If the error is the same for both reads then the first set of reads
 
  87          * is valid.  If there is a change then there is a CE no info and the
 
  88          * second set of reads is valid and should be UE info.
 
  90         if (!(info->errsts2 & 0x0003))
 
  93         if ((info->errsts ^ info->errsts2) & 0x0003) {
 
  94                 pci_read_config_dword(pdev, I82860_EAP, &info->eap);
 
  95                 pci_read_config_word(pdev, I82860_DERRCTL_STS, &info->derrsyn);
 
  99 static int i82860_process_error_info(struct mem_ctl_info *mci,
 
 100                                 struct i82860_error_info *info,
 
 105         if (!(info->errsts2 & 0x0003))
 
 111         if ((info->errsts ^ info->errsts2) & 0x0003) {
 
 112                 edac_mc_handle_ce_no_info(mci, "UE overwrote CE");
 
 113                 info->errsts = info->errsts2;
 
 116         info->eap >>= PAGE_SHIFT;
 
 117         row = edac_mc_find_csrow_by_page(mci, info->eap);
 
 119         if (info->errsts & 0x0002)
 
 120                 edac_mc_handle_ue(mci, info->eap, 0, row, "i82860 UE");
 
 122                 edac_mc_handle_ce(mci, info->eap, 0, info->derrsyn, row, 0,
 
 128 static void i82860_check(struct mem_ctl_info *mci)
 
 130         struct i82860_error_info info;
 
 132         debugf1("MC%d: %s()\n", mci->mc_idx, __func__);
 
 133         i82860_get_error_info(mci, &info);
 
 134         i82860_process_error_info(mci, &info, 1);
 
 137 static void i82860_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev)
 
 139         unsigned long last_cumul_size;
 
 140         u16 mchcfg_ddim;        /* DRAM Data Integrity Mode 0=none, 2=edac */
 
 143         struct csrow_info *csrow;
 
 146         pci_read_config_word(pdev, I82860_MCHCFG, &mchcfg_ddim);
 
 147         mchcfg_ddim = mchcfg_ddim & 0x180;
 
 150         /* The group row boundary (GRA) reg values are boundary address
 
 151          * for each DRAM row with a granularity of 16MB.  GRA regs are
 
 152          * cumulative; therefore GRA15 will contain the total memory contained
 
 155         for (index = 0; index < mci->nr_csrows; index++) {
 
 156                 csrow = &mci->csrows[index];
 
 157                 pci_read_config_word(pdev, I82860_GBA + index * 2, &value);
 
 158                 cumul_size = (value & I82860_GBA_MASK) <<
 
 159                         (I82860_GBA_SHIFT - PAGE_SHIFT);
 
 160                 debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index,
 
 163                 if (cumul_size == last_cumul_size)
 
 164                         continue;       /* not populated */
 
 166                 csrow->first_page = last_cumul_size;
 
 167                 csrow->last_page = cumul_size - 1;
 
 168                 csrow->nr_pages = cumul_size - last_cumul_size;
 
 169                 last_cumul_size = cumul_size;
 
 170                 csrow->grain = 1 << 12; /* I82860_EAP has 4KiB reolution */
 
 171                 csrow->mtype = MEM_RMBS;
 
 172                 csrow->dtype = DEV_UNKNOWN;
 
 173                 csrow->edac_mode = mchcfg_ddim ? EDAC_SECDED : EDAC_NONE;
 
 177 static int i82860_probe1(struct pci_dev *pdev, int dev_idx)
 
 179         struct mem_ctl_info *mci;
 
 180         struct i82860_error_info discard;
 
 182         /* RDRAM has channels but these don't map onto the abstractions that
 
 184            The device groups from the GRA registers seem to map reasonably
 
 185            well onto the notion of a chip select row.
 
 186            There are 16 GRA registers and since the name is associated with
 
 187            the channel and the GRA registers map to physical devices so we are
 
 188            going to make 1 channel for group.
 
 190         mci = edac_mc_alloc(0, 16, 1, 0);
 
 195         debugf3("%s(): init mci\n", __func__);
 
 196         mci->dev = &pdev->dev;
 
 197         mci->mtype_cap = MEM_FLAG_DDR;
 
 198         mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
 
 199         /* I"m not sure about this but I think that all RDRAM is SECDED */
 
 200         mci->edac_cap = EDAC_FLAG_SECDED;
 
 201         mci->mod_name = EDAC_MOD_STR;
 
 202         mci->mod_ver = I82860_REVISION;
 
 203         mci->ctl_name = i82860_devs[dev_idx].ctl_name;
 
 204         mci->dev_name = pci_name(pdev);
 
 205         mci->edac_check = i82860_check;
 
 206         mci->ctl_page_to_phys = NULL;
 
 207         i82860_init_csrows(mci, pdev);
 
 208         i82860_get_error_info(mci, &discard);   /* clear counters */
 
 210         /* Here we assume that we will never see multiple instances of this
 
 211          * type of memory controller.  The ID is therefore hardcoded to 0.
 
 213         if (edac_mc_add_mc(mci)) {
 
 214                 debugf3("%s(): failed edac_mc_add_mc()\n", __func__);
 
 218         /* allocating generic PCI control info */
 
 219         i82860_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR);
 
 222                         "%s(): Unable to create PCI control\n",
 
 225                         "%s(): PCI error report via EDAC not setup\n",
 
 229         /* get this far and it's successful */
 
 230         debugf3("%s(): success\n", __func__);
 
 239 /* returns count (>= 0), or negative on error */
 
 240 static int __devinit i82860_init_one(struct pci_dev *pdev,
 
 241                                 const struct pci_device_id *ent)
 
 245         debugf0("%s()\n", __func__);
 
 246         i82860_printk(KERN_INFO, "i82860 init one\n");
 
 248         if (pci_enable_device(pdev) < 0)
 
 251         rc = i82860_probe1(pdev, ent->driver_data);
 
 254                 mci_pdev = pci_dev_get(pdev);
 
 259 static void __devexit i82860_remove_one(struct pci_dev *pdev)
 
 261         struct mem_ctl_info *mci;
 
 263         debugf0("%s()\n", __func__);
 
 266                 edac_pci_release_generic_ctl(i82860_pci);
 
 268         if ((mci = edac_mc_del_mc(&pdev->dev)) == NULL)
 
 274 static const struct pci_device_id i82860_pci_tbl[] __devinitdata = {
 
 276          PCI_VEND_DEV(INTEL, 82860_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 
 280          }                      /* 0 terminated list. */
 
 283 MODULE_DEVICE_TABLE(pci, i82860_pci_tbl);
 
 285 static struct pci_driver i82860_driver = {
 
 286         .name = EDAC_MOD_STR,
 
 287         .probe = i82860_init_one,
 
 288         .remove = __devexit_p(i82860_remove_one),
 
 289         .id_table = i82860_pci_tbl,
 
 292 static int __init i82860_init(void)
 
 296         debugf3("%s()\n", __func__);
 
 298        /* Ensure that the OPSTATE is set correctly for POLL or NMI */
 
 301         if ((pci_rc = pci_register_driver(&i82860_driver)) < 0)
 
 305                 mci_pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
 
 306                                         PCI_DEVICE_ID_INTEL_82860_0, NULL);
 
 308                 if (mci_pdev == NULL) {
 
 309                         debugf0("860 pci_get_device fail\n");
 
 314                 pci_rc = i82860_init_one(mci_pdev, i82860_pci_tbl);
 
 317                         debugf0("860 init fail\n");
 
 326         pci_unregister_driver(&i82860_driver);
 
 329         if (mci_pdev != NULL)
 
 330                 pci_dev_put(mci_pdev);
 
 335 static void __exit i82860_exit(void)
 
 337         debugf3("%s()\n", __func__);
 
 339         pci_unregister_driver(&i82860_driver);
 
 341         if (mci_pdev != NULL)
 
 342                 pci_dev_put(mci_pdev);
 
 345 module_init(i82860_init);
 
 346 module_exit(i82860_exit);
 
 348 MODULE_LICENSE("GPL");
 
 349 MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com) "
 
 350                 "Ben Woodard <woodard@redhat.com>");
 
 351 MODULE_DESCRIPTION("ECC support for Intel 82860 memory hub controllers");
 
 353 module_param(edac_op_state, int, 0444);
 
 354 MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI");