359 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * amd8131_edac.c, AMD8131 hypertransport chip EDAC kernel module4 *5 * Copyright (c) 2008 Wind River Systems, Inc.6 *7 * Authors: Cao Qingtao <qingtao.cao@windriver.com>8 * Benjamin Walsh <benjamin.walsh@windriver.com>9 * Hu Yongqi <yongqi.hu@windriver.com>10 */11 12#include <linux/module.h>13#include <linux/init.h>14#include <linux/interrupt.h>15#include <linux/io.h>16#include <linux/bitops.h>17#include <linux/edac.h>18#include <linux/pci_ids.h>19 20#include "edac_module.h"21#include "amd8131_edac.h"22 23#define AMD8131_EDAC_REVISION " Ver: 1.0.0"24#define AMD8131_EDAC_MOD_STR "amd8131_edac"25 26/* Wrapper functions for accessing PCI configuration space */27static void edac_pci_read_dword(struct pci_dev *dev, int reg, u32 *val32)28{29 int ret;30 31 ret = pci_read_config_dword(dev, reg, val32);32 if (ret != 0)33 printk(KERN_ERR AMD8131_EDAC_MOD_STR34 " PCI Access Read Error at 0x%x\n", reg);35}36 37static void edac_pci_write_dword(struct pci_dev *dev, int reg, u32 val32)38{39 int ret;40 41 ret = pci_write_config_dword(dev, reg, val32);42 if (ret != 0)43 printk(KERN_ERR AMD8131_EDAC_MOD_STR44 " PCI Access Write Error at 0x%x\n", reg);45}46 47/* Support up to two AMD8131 chipsets on a platform */48static struct amd8131_dev_info amd8131_devices[] = {49 {50 .inst = NORTH_A,51 .devfn = DEVFN_PCIX_BRIDGE_NORTH_A,52 .ctl_name = "AMD8131_PCIX_NORTH_A",53 },54 {55 .inst = NORTH_B,56 .devfn = DEVFN_PCIX_BRIDGE_NORTH_B,57 .ctl_name = "AMD8131_PCIX_NORTH_B",58 },59 {60 .inst = SOUTH_A,61 .devfn = DEVFN_PCIX_BRIDGE_SOUTH_A,62 .ctl_name = "AMD8131_PCIX_SOUTH_A",63 },64 {65 .inst = SOUTH_B,66 .devfn = DEVFN_PCIX_BRIDGE_SOUTH_B,67 .ctl_name = "AMD8131_PCIX_SOUTH_B",68 },69 {.inst = NO_BRIDGE,},70};71 72static void amd8131_pcix_init(struct amd8131_dev_info *dev_info)73{74 u32 val32;75 struct pci_dev *dev = dev_info->dev;76 77 /* First clear error detection flags */78 edac_pci_read_dword(dev, REG_MEM_LIM, &val32);79 if (val32 & MEM_LIMIT_MASK)80 edac_pci_write_dword(dev, REG_MEM_LIM, val32);81 82 /* Clear Discard Timer Timedout flag */83 edac_pci_read_dword(dev, REG_INT_CTLR, &val32);84 if (val32 & INT_CTLR_DTS)85 edac_pci_write_dword(dev, REG_INT_CTLR, val32);86 87 /* Clear CRC Error flag on link side A */88 edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32);89 if (val32 & LNK_CTRL_CRCERR_A)90 edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32);91 92 /* Clear CRC Error flag on link side B */93 edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32);94 if (val32 & LNK_CTRL_CRCERR_B)95 edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32);96 97 /*98 * Then enable all error detections.99 *100 * Setup Discard Timer Sync Flood Enable,101 * System Error Enable and Parity Error Enable.102 */103 edac_pci_read_dword(dev, REG_INT_CTLR, &val32);104 val32 |= INT_CTLR_PERR | INT_CTLR_SERR | INT_CTLR_DTSE;105 edac_pci_write_dword(dev, REG_INT_CTLR, val32);106 107 /* Enable overall SERR Error detection */108 edac_pci_read_dword(dev, REG_STS_CMD, &val32);109 val32 |= STS_CMD_SERREN;110 edac_pci_write_dword(dev, REG_STS_CMD, val32);111 112 /* Setup CRC Flood Enable for link side A */113 edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32);114 val32 |= LNK_CTRL_CRCFEN;115 edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32);116 117 /* Setup CRC Flood Enable for link side B */118 edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32);119 val32 |= LNK_CTRL_CRCFEN;120 edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32);121}122 123static void amd8131_pcix_exit(struct amd8131_dev_info *dev_info)124{125 u32 val32;126 struct pci_dev *dev = dev_info->dev;127 128 /* Disable SERR, PERR and DTSE Error detection */129 edac_pci_read_dword(dev, REG_INT_CTLR, &val32);130 val32 &= ~(INT_CTLR_PERR | INT_CTLR_SERR | INT_CTLR_DTSE);131 edac_pci_write_dword(dev, REG_INT_CTLR, val32);132 133 /* Disable overall System Error detection */134 edac_pci_read_dword(dev, REG_STS_CMD, &val32);135 val32 &= ~STS_CMD_SERREN;136 edac_pci_write_dword(dev, REG_STS_CMD, val32);137 138 /* Disable CRC Sync Flood on link side A */139 edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32);140 val32 &= ~LNK_CTRL_CRCFEN;141 edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32);142 143 /* Disable CRC Sync Flood on link side B */144 edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32);145 val32 &= ~LNK_CTRL_CRCFEN;146 edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32);147}148 149static void amd8131_pcix_check(struct edac_pci_ctl_info *edac_dev)150{151 struct amd8131_dev_info *dev_info = edac_dev->pvt_info;152 struct pci_dev *dev = dev_info->dev;153 u32 val32;154 155 /* Check PCI-X Bridge Memory Base-Limit Register for errors */156 edac_pci_read_dword(dev, REG_MEM_LIM, &val32);157 if (val32 & MEM_LIMIT_MASK) {158 printk(KERN_INFO "Error(s) in mem limit register "159 "on %s bridge\n", dev_info->ctl_name);160 printk(KERN_INFO "DPE: %d, RSE: %d, RMA: %d\n"161 "RTA: %d, STA: %d, MDPE: %d\n",162 val32 & MEM_LIMIT_DPE,163 val32 & MEM_LIMIT_RSE,164 val32 & MEM_LIMIT_RMA,165 val32 & MEM_LIMIT_RTA,166 val32 & MEM_LIMIT_STA,167 val32 & MEM_LIMIT_MDPE);168 169 val32 |= MEM_LIMIT_MASK;170 edac_pci_write_dword(dev, REG_MEM_LIM, val32);171 172 edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);173 }174 175 /* Check if Discard Timer timed out */176 edac_pci_read_dword(dev, REG_INT_CTLR, &val32);177 if (val32 & INT_CTLR_DTS) {178 printk(KERN_INFO "Error(s) in interrupt and control register "179 "on %s bridge\n", dev_info->ctl_name);180 printk(KERN_INFO "DTS: %d\n", val32 & INT_CTLR_DTS);181 182 val32 |= INT_CTLR_DTS;183 edac_pci_write_dword(dev, REG_INT_CTLR, val32);184 185 edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);186 }187 188 /* Check if CRC error happens on link side A */189 edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32);190 if (val32 & LNK_CTRL_CRCERR_A) {191 printk(KERN_INFO "Error(s) in link conf and control register "192 "on %s bridge\n", dev_info->ctl_name);193 printk(KERN_INFO "CRCERR: %d\n", val32 & LNK_CTRL_CRCERR_A);194 195 val32 |= LNK_CTRL_CRCERR_A;196 edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32);197 198 edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);199 }200 201 /* Check if CRC error happens on link side B */202 edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32);203 if (val32 & LNK_CTRL_CRCERR_B) {204 printk(KERN_INFO "Error(s) in link conf and control register "205 "on %s bridge\n", dev_info->ctl_name);206 printk(KERN_INFO "CRCERR: %d\n", val32 & LNK_CTRL_CRCERR_B);207 208 val32 |= LNK_CTRL_CRCERR_B;209 edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32);210 211 edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);212 }213}214 215static struct amd8131_info amd8131_chipset = {216 .err_dev = PCI_DEVICE_ID_AMD_8131_APIC,217 .devices = amd8131_devices,218 .init = amd8131_pcix_init,219 .exit = amd8131_pcix_exit,220 .check = amd8131_pcix_check,221};222 223/*224 * There are 4 PCIX Bridges on ATCA-6101 that share the same PCI Device ID,225 * so amd8131_probe() would be called by kernel 4 times, with different226 * address of pci_dev for each of them each time.227 */228static int amd8131_probe(struct pci_dev *dev, const struct pci_device_id *id)229{230 struct amd8131_dev_info *dev_info;231 232 for (dev_info = amd8131_chipset.devices; dev_info->inst != NO_BRIDGE;233 dev_info++)234 if (dev_info->devfn == dev->devfn)235 break;236 237 if (dev_info->inst == NO_BRIDGE) /* should never happen */238 return -ENODEV;239 240 /*241 * We can't call pci_get_device() as we are used to do because242 * there are 4 of them but pci_dev_get() instead.243 */244 dev_info->dev = pci_dev_get(dev);245 246 if (pci_enable_device(dev_info->dev)) {247 pci_dev_put(dev_info->dev);248 printk(KERN_ERR "failed to enable:"249 "vendor %x, device %x, devfn %x, name %s\n",250 PCI_VENDOR_ID_AMD, amd8131_chipset.err_dev,251 dev_info->devfn, dev_info->ctl_name);252 return -ENODEV;253 }254 255 /*256 * we do not allocate extra private structure for257 * edac_pci_ctl_info, but make use of existing258 * one instead.259 */260 dev_info->edac_idx = edac_pci_alloc_index();261 dev_info->edac_dev = edac_pci_alloc_ctl_info(0, dev_info->ctl_name);262 if (!dev_info->edac_dev)263 return -ENOMEM;264 265 dev_info->edac_dev->pvt_info = dev_info;266 dev_info->edac_dev->dev = &dev_info->dev->dev;267 dev_info->edac_dev->mod_name = AMD8131_EDAC_MOD_STR;268 dev_info->edac_dev->ctl_name = dev_info->ctl_name;269 dev_info->edac_dev->dev_name = dev_name(&dev_info->dev->dev);270 271 if (edac_op_state == EDAC_OPSTATE_POLL)272 dev_info->edac_dev->edac_check = amd8131_chipset.check;273 274 if (amd8131_chipset.init)275 amd8131_chipset.init(dev_info);276 277 if (edac_pci_add_device(dev_info->edac_dev, dev_info->edac_idx) > 0) {278 printk(KERN_ERR "failed edac_pci_add_device() for %s\n",279 dev_info->ctl_name);280 edac_pci_free_ctl_info(dev_info->edac_dev);281 return -ENODEV;282 }283 284 printk(KERN_INFO "added one device on AMD8131 "285 "vendor %x, device %x, devfn %x, name %s\n",286 PCI_VENDOR_ID_AMD, amd8131_chipset.err_dev,287 dev_info->devfn, dev_info->ctl_name);288 289 return 0;290}291 292static void amd8131_remove(struct pci_dev *dev)293{294 struct amd8131_dev_info *dev_info;295 296 for (dev_info = amd8131_chipset.devices; dev_info->inst != NO_BRIDGE;297 dev_info++)298 if (dev_info->devfn == dev->devfn)299 break;300 301 if (dev_info->inst == NO_BRIDGE) /* should never happen */302 return;303 304 if (dev_info->edac_dev) {305 edac_pci_del_device(dev_info->edac_dev->dev);306 edac_pci_free_ctl_info(dev_info->edac_dev);307 }308 309 if (amd8131_chipset.exit)310 amd8131_chipset.exit(dev_info);311 312 pci_dev_put(dev_info->dev);313}314 315static const struct pci_device_id amd8131_edac_pci_tbl[] = {316 {317 PCI_VEND_DEV(AMD, 8131_BRIDGE),318 .subvendor = PCI_ANY_ID,319 .subdevice = PCI_ANY_ID,320 .class = 0,321 .class_mask = 0,322 .driver_data = 0,323 },324 {325 0,326 } /* table is NULL-terminated */327};328MODULE_DEVICE_TABLE(pci, amd8131_edac_pci_tbl);329 330static struct pci_driver amd8131_edac_driver = {331 .name = AMD8131_EDAC_MOD_STR,332 .probe = amd8131_probe,333 .remove = amd8131_remove,334 .id_table = amd8131_edac_pci_tbl,335};336 337static int __init amd8131_edac_init(void)338{339 printk(KERN_INFO "AMD8131 EDAC driver " AMD8131_EDAC_REVISION "\n");340 printk(KERN_INFO "\t(c) 2008 Wind River Systems, Inc.\n");341 342 /* Only POLL mode supported so far */343 edac_op_state = EDAC_OPSTATE_POLL;344 345 return pci_register_driver(&amd8131_edac_driver);346}347 348static void __exit amd8131_edac_exit(void)349{350 pci_unregister_driver(&amd8131_edac_driver);351}352 353module_init(amd8131_edac_init);354module_exit(amd8131_edac_exit);355 356MODULE_LICENSE("GPL");357MODULE_AUTHOR("Cao Qingtao <qingtao.cao@windriver.com>");358MODULE_DESCRIPTION("AMD8131 HyperTransport PCI-X Tunnel EDAC kernel module");359