Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Copyright 2018, 2019 Cisco Systems
0004  */
0005 
0006 #include <linux/edac.h>
0007 #include <linux/module.h>
0008 #include <linux/init.h>
0009 #include <linux/interrupt.h>
0010 #include <linux/platform_device.h>
0011 #include <linux/stop_machine.h>
0012 #include <linux/io.h>
0013 #include <linux/of_address.h>
0014 #include <linux/regmap.h>
0015 #include "edac_module.h"
0016 
0017 
0018 #define DRV_NAME "aspeed-edac"
0019 
0020 
0021 #define ASPEED_MCR_PROT        0x00 /* protection key register */
0022 #define ASPEED_MCR_CONF        0x04 /* configuration register */
0023 #define ASPEED_MCR_INTR_CTRL   0x50 /* interrupt control/status register */
0024 #define ASPEED_MCR_ADDR_UNREC  0x58 /* address of first un-recoverable error */
0025 #define ASPEED_MCR_ADDR_REC    0x5c /* address of last recoverable error */
0026 #define ASPEED_MCR_LAST        ASPEED_MCR_ADDR_REC
0027 
0028 
0029 #define ASPEED_MCR_PROT_PASSWD              0xfc600309
0030 #define ASPEED_MCR_CONF_DRAM_TYPE               BIT(4)
0031 #define ASPEED_MCR_CONF_ECC                     BIT(7)
0032 #define ASPEED_MCR_INTR_CTRL_CLEAR             BIT(31)
0033 #define ASPEED_MCR_INTR_CTRL_CNT_REC   GENMASK(23, 16)
0034 #define ASPEED_MCR_INTR_CTRL_CNT_UNREC GENMASK(15, 12)
0035 #define ASPEED_MCR_INTR_CTRL_ENABLE  (BIT(0) | BIT(1))
0036 
0037 
0038 static struct regmap *aspeed_regmap;
0039 
0040 
0041 static int regmap_reg_write(void *context, unsigned int reg, unsigned int val)
0042 {
0043     void __iomem *regs = (void __iomem *)context;
0044 
0045     /* enable write to MCR register set */
0046     writel(ASPEED_MCR_PROT_PASSWD, regs + ASPEED_MCR_PROT);
0047 
0048     writel(val, regs + reg);
0049 
0050     /* disable write to MCR register set */
0051     writel(~ASPEED_MCR_PROT_PASSWD, regs + ASPEED_MCR_PROT);
0052 
0053     return 0;
0054 }
0055 
0056 
0057 static int regmap_reg_read(void *context, unsigned int reg, unsigned int *val)
0058 {
0059     void __iomem *regs = (void __iomem *)context;
0060 
0061     *val = readl(regs + reg);
0062 
0063     return 0;
0064 }
0065 
0066 static bool regmap_is_volatile(struct device *dev, unsigned int reg)
0067 {
0068     switch (reg) {
0069     case ASPEED_MCR_PROT:
0070     case ASPEED_MCR_INTR_CTRL:
0071     case ASPEED_MCR_ADDR_UNREC:
0072     case ASPEED_MCR_ADDR_REC:
0073         return true;
0074     default:
0075         return false;
0076     }
0077 }
0078 
0079 
0080 static const struct regmap_config aspeed_regmap_config = {
0081     .reg_bits = 32,
0082     .val_bits = 32,
0083     .reg_stride = 4,
0084     .max_register = ASPEED_MCR_LAST,
0085     .reg_write = regmap_reg_write,
0086     .reg_read = regmap_reg_read,
0087     .volatile_reg = regmap_is_volatile,
0088     .fast_io = true,
0089 };
0090 
0091 
0092 static void count_rec(struct mem_ctl_info *mci, u8 rec_cnt, u32 rec_addr)
0093 {
0094     struct csrow_info *csrow = mci->csrows[0];
0095     u32 page, offset, syndrome;
0096 
0097     if (!rec_cnt)
0098         return;
0099 
0100     /* report first few errors (if there are) */
0101     /* note: no addresses are recorded */
0102     if (rec_cnt > 1) {
0103         /* page, offset and syndrome are not available */
0104         page = 0;
0105         offset = 0;
0106         syndrome = 0;
0107         edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, rec_cnt-1,
0108                      page, offset, syndrome, 0, 0, -1,
0109                      "address(es) not available", "");
0110     }
0111 
0112     /* report last error */
0113     /* note: rec_addr is the last recoverable error addr */
0114     page = rec_addr >> PAGE_SHIFT;
0115     offset = rec_addr & ~PAGE_MASK;
0116     /* syndrome is not available */
0117     syndrome = 0;
0118     edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1,
0119                  csrow->first_page + page, offset, syndrome,
0120                  0, 0, -1, "", "");
0121 }
0122 
0123 
0124 static void count_un_rec(struct mem_ctl_info *mci, u8 un_rec_cnt,
0125              u32 un_rec_addr)
0126 {
0127     struct csrow_info *csrow = mci->csrows[0];
0128     u32 page, offset, syndrome;
0129 
0130     if (!un_rec_cnt)
0131         return;
0132 
0133     /* report 1. error */
0134     /* note: un_rec_addr is the first unrecoverable error addr */
0135     page = un_rec_addr >> PAGE_SHIFT;
0136     offset = un_rec_addr & ~PAGE_MASK;
0137     /* syndrome is not available */
0138     syndrome = 0;
0139     edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1,
0140                  csrow->first_page + page, offset, syndrome,
0141                  0, 0, -1, "", "");
0142 
0143     /* report further errors (if there are) */
0144     /* note: no addresses are recorded */
0145     if (un_rec_cnt > 1) {
0146         /* page, offset and syndrome are not available */
0147         page = 0;
0148         offset = 0;
0149         syndrome = 0;
0150         edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, un_rec_cnt-1,
0151                      page, offset, syndrome, 0, 0, -1,
0152                      "address(es) not available", "");
0153     }
0154 }
0155 
0156 
0157 static irqreturn_t mcr_isr(int irq, void *arg)
0158 {
0159     struct mem_ctl_info *mci = arg;
0160     u32 rec_addr, un_rec_addr;
0161     u32 reg50, reg5c, reg58;
0162     u8  rec_cnt, un_rec_cnt;
0163 
0164     regmap_read(aspeed_regmap, ASPEED_MCR_INTR_CTRL, &reg50);
0165     dev_dbg(mci->pdev, "received edac interrupt w/ mcr register 50: 0x%x\n",
0166         reg50);
0167 
0168     /* collect data about recoverable and unrecoverable errors */
0169     rec_cnt = (reg50 & ASPEED_MCR_INTR_CTRL_CNT_REC) >> 16;
0170     un_rec_cnt = (reg50 & ASPEED_MCR_INTR_CTRL_CNT_UNREC) >> 12;
0171 
0172     dev_dbg(mci->pdev, "%d recoverable interrupts and %d unrecoverable interrupts\n",
0173         rec_cnt, un_rec_cnt);
0174 
0175     regmap_read(aspeed_regmap, ASPEED_MCR_ADDR_UNREC, &reg58);
0176     un_rec_addr = reg58;
0177 
0178     regmap_read(aspeed_regmap, ASPEED_MCR_ADDR_REC, &reg5c);
0179     rec_addr = reg5c;
0180 
0181     /* clear interrupt flags and error counters: */
0182     regmap_update_bits(aspeed_regmap, ASPEED_MCR_INTR_CTRL,
0183                ASPEED_MCR_INTR_CTRL_CLEAR,
0184                ASPEED_MCR_INTR_CTRL_CLEAR);
0185 
0186     regmap_update_bits(aspeed_regmap, ASPEED_MCR_INTR_CTRL,
0187                ASPEED_MCR_INTR_CTRL_CLEAR, 0);
0188 
0189     /* process recoverable and unrecoverable errors */
0190     count_rec(mci, rec_cnt, rec_addr);
0191     count_un_rec(mci, un_rec_cnt, un_rec_addr);
0192 
0193     if (!rec_cnt && !un_rec_cnt)
0194         dev_dbg(mci->pdev, "received edac interrupt, but did not find any ECC counters\n");
0195 
0196     regmap_read(aspeed_regmap, ASPEED_MCR_INTR_CTRL, &reg50);
0197     dev_dbg(mci->pdev, "edac interrupt handled. mcr reg 50 is now: 0x%x\n",
0198         reg50);
0199 
0200     return IRQ_HANDLED;
0201 }
0202 
0203 
0204 static int config_irq(void *ctx, struct platform_device *pdev)
0205 {
0206     int irq;
0207     int rc;
0208 
0209     /* register interrupt handler */
0210     irq = platform_get_irq(pdev, 0);
0211     dev_dbg(&pdev->dev, "got irq %d\n", irq);
0212     if (irq < 0)
0213         return irq;
0214 
0215     rc = devm_request_irq(&pdev->dev, irq, mcr_isr, IRQF_TRIGGER_HIGH,
0216                   DRV_NAME, ctx);
0217     if (rc) {
0218         dev_err(&pdev->dev, "unable to request irq %d\n", irq);
0219         return rc;
0220     }
0221 
0222     /* enable interrupts */
0223     regmap_update_bits(aspeed_regmap, ASPEED_MCR_INTR_CTRL,
0224                ASPEED_MCR_INTR_CTRL_ENABLE,
0225                ASPEED_MCR_INTR_CTRL_ENABLE);
0226 
0227     return 0;
0228 }
0229 
0230 
0231 static int init_csrows(struct mem_ctl_info *mci)
0232 {
0233     struct csrow_info *csrow = mci->csrows[0];
0234     u32 nr_pages, dram_type;
0235     struct dimm_info *dimm;
0236     struct device_node *np;
0237     struct resource r;
0238     u32 reg04;
0239     int rc;
0240 
0241     /* retrieve info about physical memory from device tree */
0242     np = of_find_node_by_name(NULL, "memory");
0243     if (!np) {
0244         dev_err(mci->pdev, "dt: missing /memory node\n");
0245         return -ENODEV;
0246     }
0247 
0248     rc = of_address_to_resource(np, 0, &r);
0249 
0250     of_node_put(np);
0251 
0252     if (rc) {
0253         dev_err(mci->pdev, "dt: failed requesting resource for /memory node\n");
0254         return rc;
0255     }
0256 
0257     dev_dbg(mci->pdev, "dt: /memory node resources: first page %pR, PAGE_SHIFT macro=0x%x\n",
0258         &r, PAGE_SHIFT);
0259 
0260     csrow->first_page = r.start >> PAGE_SHIFT;
0261     nr_pages = resource_size(&r) >> PAGE_SHIFT;
0262     csrow->last_page = csrow->first_page + nr_pages - 1;
0263 
0264     regmap_read(aspeed_regmap, ASPEED_MCR_CONF, &reg04);
0265     dram_type = (reg04 & ASPEED_MCR_CONF_DRAM_TYPE) ? MEM_DDR4 : MEM_DDR3;
0266 
0267     dimm = csrow->channels[0]->dimm;
0268     dimm->mtype = dram_type;
0269     dimm->edac_mode = EDAC_SECDED;
0270     dimm->nr_pages = nr_pages / csrow->nr_channels;
0271 
0272     dev_dbg(mci->pdev, "initialized dimm with first_page=0x%lx and nr_pages=0x%x\n",
0273         csrow->first_page, nr_pages);
0274 
0275     return 0;
0276 }
0277 
0278 
0279 static int aspeed_probe(struct platform_device *pdev)
0280 {
0281     struct device *dev = &pdev->dev;
0282     struct edac_mc_layer layers[2];
0283     struct mem_ctl_info *mci;
0284     void __iomem *regs;
0285     u32 reg04;
0286     int rc;
0287 
0288     regs = devm_platform_ioremap_resource(pdev, 0);
0289     if (IS_ERR(regs))
0290         return PTR_ERR(regs);
0291 
0292     aspeed_regmap = devm_regmap_init(dev, NULL, (__force void *)regs,
0293                      &aspeed_regmap_config);
0294     if (IS_ERR(aspeed_regmap))
0295         return PTR_ERR(aspeed_regmap);
0296 
0297     /* bail out if ECC mode is not configured */
0298     regmap_read(aspeed_regmap, ASPEED_MCR_CONF, &reg04);
0299     if (!(reg04 & ASPEED_MCR_CONF_ECC)) {
0300         dev_err(&pdev->dev, "ECC mode is not configured in u-boot\n");
0301         return -EPERM;
0302     }
0303 
0304     edac_op_state = EDAC_OPSTATE_INT;
0305 
0306     /* allocate & init EDAC MC data structure */
0307     layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
0308     layers[0].size = 1;
0309     layers[0].is_virt_csrow = true;
0310     layers[1].type = EDAC_MC_LAYER_CHANNEL;
0311     layers[1].size = 1;
0312     layers[1].is_virt_csrow = false;
0313 
0314     mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers, 0);
0315     if (!mci)
0316         return -ENOMEM;
0317 
0318     mci->pdev = &pdev->dev;
0319     mci->mtype_cap = MEM_FLAG_DDR3 | MEM_FLAG_DDR4;
0320     mci->edac_ctl_cap = EDAC_FLAG_SECDED;
0321     mci->edac_cap = EDAC_FLAG_SECDED;
0322     mci->scrub_cap = SCRUB_FLAG_HW_SRC;
0323     mci->scrub_mode = SCRUB_HW_SRC;
0324     mci->mod_name = DRV_NAME;
0325     mci->ctl_name = "MIC";
0326     mci->dev_name = dev_name(&pdev->dev);
0327 
0328     rc = init_csrows(mci);
0329     if (rc) {
0330         dev_err(&pdev->dev, "failed to init csrows\n");
0331         goto probe_exit02;
0332     }
0333 
0334     platform_set_drvdata(pdev, mci);
0335 
0336     /* register with edac core */
0337     rc = edac_mc_add_mc(mci);
0338     if (rc) {
0339         dev_err(&pdev->dev, "failed to register with EDAC core\n");
0340         goto probe_exit02;
0341     }
0342 
0343     /* register interrupt handler and enable interrupts */
0344     rc = config_irq(mci, pdev);
0345     if (rc) {
0346         dev_err(&pdev->dev, "failed setting up irq\n");
0347         goto probe_exit01;
0348     }
0349 
0350     return 0;
0351 
0352 probe_exit01:
0353     edac_mc_del_mc(&pdev->dev);
0354 probe_exit02:
0355     edac_mc_free(mci);
0356     return rc;
0357 }
0358 
0359 
0360 static int aspeed_remove(struct platform_device *pdev)
0361 {
0362     struct mem_ctl_info *mci;
0363 
0364     /* disable interrupts */
0365     regmap_update_bits(aspeed_regmap, ASPEED_MCR_INTR_CTRL,
0366                ASPEED_MCR_INTR_CTRL_ENABLE, 0);
0367 
0368     /* free resources */
0369     mci = edac_mc_del_mc(&pdev->dev);
0370     if (mci)
0371         edac_mc_free(mci);
0372 
0373     return 0;
0374 }
0375 
0376 
0377 static const struct of_device_id aspeed_of_match[] = {
0378     { .compatible = "aspeed,ast2400-sdram-edac" },
0379     { .compatible = "aspeed,ast2500-sdram-edac" },
0380     { .compatible = "aspeed,ast2600-sdram-edac" },
0381     {},
0382 };
0383 
0384 MODULE_DEVICE_TABLE(of, aspeed_of_match);
0385 
0386 static struct platform_driver aspeed_driver = {
0387     .driver     = {
0388         .name   = DRV_NAME,
0389         .of_match_table = aspeed_of_match
0390     },
0391     .probe      = aspeed_probe,
0392     .remove     = aspeed_remove
0393 };
0394 module_platform_driver(aspeed_driver);
0395 
0396 MODULE_LICENSE("GPL");
0397 MODULE_AUTHOR("Stefan Schaeckeler <sschaeck@cisco.com>");
0398 MODULE_DESCRIPTION("Aspeed BMC SoC EDAC driver");
0399 MODULE_VERSION("1.0");