^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2017-2018, Intel Corporation. All rights reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright Altera Corporation (C) 2014-2016. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2011-2012 Calxeda, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <asm/cacheflush.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/edac.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/firmware/intel/stratix10-smc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/genalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/irqchip/chained_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/mfd/altera-sysmgr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/mfd/syscon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/notifier.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "altera_edac.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "edac_module.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define EDAC_MOD_STR "altera_edac"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define EDAC_DEVICE "Altera"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #ifdef CONFIG_EDAC_ALTERA_SDRAM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static const struct altr_sdram_prv_data c5_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) .ecc_ctrl_offset = CV_CTLCFG_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) .ecc_ctl_en_mask = CV_CTLCFG_ECC_AUTO_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) .ecc_stat_offset = CV_DRAMSTS_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) .ecc_stat_ce_mask = CV_DRAMSTS_SBEERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) .ecc_stat_ue_mask = CV_DRAMSTS_DBEERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) .ecc_saddr_offset = CV_ERRADDR_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) .ecc_daddr_offset = CV_ERRADDR_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) .ecc_cecnt_offset = CV_SBECOUNT_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) .ecc_uecnt_offset = CV_DBECOUNT_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) .ecc_irq_en_offset = CV_DRAMINTR_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) .ecc_irq_en_mask = CV_DRAMINTR_INTREN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) .ecc_irq_clr_offset = CV_DRAMINTR_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .ecc_irq_clr_mask = (CV_DRAMINTR_INTRCLR | CV_DRAMINTR_INTREN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) .ecc_cnt_rst_offset = CV_DRAMINTR_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .ecc_cnt_rst_mask = CV_DRAMINTR_INTRCLR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .ce_ue_trgr_offset = CV_CTLCFG_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .ce_set_mask = CV_CTLCFG_GEN_SB_ERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .ue_set_mask = CV_CTLCFG_GEN_DB_ERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static const struct altr_sdram_prv_data a10_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .ecc_ctrl_offset = A10_ECCCTRL1_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) .ecc_ctl_en_mask = A10_ECCCTRL1_ECC_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) .ecc_stat_offset = A10_INTSTAT_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .ecc_stat_ce_mask = A10_INTSTAT_SBEERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .ecc_stat_ue_mask = A10_INTSTAT_DBEERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) .ecc_saddr_offset = A10_SERRADDR_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) .ecc_daddr_offset = A10_DERRADDR_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) .ecc_irq_en_offset = A10_ERRINTEN_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) .ecc_irq_en_mask = A10_ECC_IRQ_EN_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) .ecc_irq_clr_offset = A10_INTSTAT_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .ecc_irq_clr_mask = (A10_INTSTAT_SBEERR | A10_INTSTAT_DBEERR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .ecc_cnt_rst_offset = A10_ECCCTRL1_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .ecc_cnt_rst_mask = A10_ECC_CNT_RESET_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .ce_ue_trgr_offset = A10_DIAGINTTEST_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .ce_set_mask = A10_DIAGINT_TSERRA_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) .ue_set_mask = A10_DIAGINT_TDERRA_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /*********************** EDAC Memory Controller Functions ****************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* The SDRAM controller uses the EDAC Memory Controller framework. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static irqreturn_t altr_sdram_mc_err_handler(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct mem_ctl_info *mci = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct altr_sdram_mc_data *drvdata = mci->pvt_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) const struct altr_sdram_prv_data *priv = drvdata->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) u32 status, err_count = 1, err_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) regmap_read(drvdata->mc_vbase, priv->ecc_stat_offset, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (status & priv->ecc_stat_ue_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) regmap_read(drvdata->mc_vbase, priv->ecc_daddr_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) &err_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (priv->ecc_uecnt_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) regmap_read(drvdata->mc_vbase, priv->ecc_uecnt_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) &err_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) panic("\nEDAC: [%d Uncorrectable errors @ 0x%08X]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) err_count, err_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (status & priv->ecc_stat_ce_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) regmap_read(drvdata->mc_vbase, priv->ecc_saddr_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) &err_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (priv->ecc_uecnt_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) regmap_read(drvdata->mc_vbase, priv->ecc_cecnt_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) &err_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, err_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) err_addr >> PAGE_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) err_addr & ~PAGE_MASK, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 0, 0, -1, mci->ctl_name, "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* Clear IRQ to resume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) regmap_write(drvdata->mc_vbase, priv->ecc_irq_clr_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) priv->ecc_irq_clr_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static ssize_t altr_sdr_mc_err_inject_write(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) const char __user *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct mem_ctl_info *mci = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct altr_sdram_mc_data *drvdata = mci->pvt_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) const struct altr_sdram_prv_data *priv = drvdata->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) u32 *ptemp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) dma_addr_t dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) u32 reg, read_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) ptemp = dma_alloc_coherent(mci->pdev, 16, &dma_handle, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (!ptemp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) dma_free_coherent(mci->pdev, 16, ptemp, dma_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) edac_printk(KERN_ERR, EDAC_MC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) "Inject: Buffer Allocation error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) regmap_read(drvdata->mc_vbase, priv->ce_ue_trgr_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) &read_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) read_reg &= ~(priv->ce_set_mask | priv->ue_set_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /* Error are injected by writing a word while the SBE or DBE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * bit in the CTLCFG register is set. Reading the word will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * trigger the SBE or DBE error and the corresponding IRQ.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (count == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) edac_printk(KERN_ALERT, EDAC_MC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) "Inject Double bit error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) local_irq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) regmap_write(drvdata->mc_vbase, priv->ce_ue_trgr_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) (read_reg | priv->ue_set_mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) local_irq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) edac_printk(KERN_ALERT, EDAC_MC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) "Inject Single bit error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) local_irq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) regmap_write(drvdata->mc_vbase, priv->ce_ue_trgr_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) (read_reg | priv->ce_set_mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) local_irq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ptemp[0] = 0x5A5A5A5A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) ptemp[1] = 0xA5A5A5A5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /* Clear the error injection bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) regmap_write(drvdata->mc_vbase, priv->ce_ue_trgr_offset, read_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /* Ensure it has been written out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * To trigger the error, we need to read the data back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * (the data was written with errors above).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * The READ_ONCE macros and printk are used to prevent the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * the compiler optimizing these reads out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) reg = READ_ONCE(ptemp[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) read_reg = READ_ONCE(ptemp[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* Force Read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) edac_printk(KERN_ALERT, EDAC_MC, "Read Data [0x%X, 0x%X]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) reg, read_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) dma_free_coherent(mci->pdev, 16, ptemp, dma_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static const struct file_operations altr_sdr_mc_debug_inject_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) .open = simple_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) .write = altr_sdr_mc_err_inject_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) .llseek = generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static void altr_sdr_mc_create_debugfs_nodes(struct mem_ctl_info *mci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (!IS_ENABLED(CONFIG_EDAC_DEBUG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (!mci->debugfs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) edac_debugfs_create_file("altr_trigger", S_IWUSR, mci->debugfs, mci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) &altr_sdr_mc_debug_inject_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* Get total memory size from Open Firmware DTB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static unsigned long get_total_mem(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct device_node *np = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) struct resource res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) unsigned long total_mem = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) for_each_node_by_type(np, "memory") {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ret = of_address_to_resource(np, 0, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) total_mem += resource_size(&res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) edac_dbg(0, "total_mem 0x%lx\n", total_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return total_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static const struct of_device_id altr_sdram_ctrl_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) { .compatible = "altr,sdram-edac", .data = &c5_data},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) { .compatible = "altr,sdram-edac-a10", .data = &a10_data},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) MODULE_DEVICE_TABLE(of, altr_sdram_ctrl_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static int a10_init(struct regmap *mc_vbase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (regmap_update_bits(mc_vbase, A10_INTMODE_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) A10_INTMODE_SB_INT, A10_INTMODE_SB_INT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) edac_printk(KERN_ERR, EDAC_MC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) "Error setting SB IRQ mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (regmap_write(mc_vbase, A10_SERRCNTREG_OFST, 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) edac_printk(KERN_ERR, EDAC_MC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) "Error setting trigger count\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static int a10_unmask_irq(struct platform_device *pdev, u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) void __iomem *sm_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (!request_mem_region(A10_SYMAN_INTMASK_CLR, sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) dev_name(&pdev->dev))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) edac_printk(KERN_ERR, EDAC_MC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) "Unable to request mem region\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) sm_base = ioremap(A10_SYMAN_INTMASK_CLR, sizeof(u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (!sm_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) edac_printk(KERN_ERR, EDAC_MC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) "Unable to ioremap device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) iowrite32(mask, sm_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) iounmap(sm_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) release_mem_region(A10_SYMAN_INTMASK_CLR, sizeof(u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static int altr_sdram_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) const struct of_device_id *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct edac_mc_layer layers[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct mem_ctl_info *mci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) struct altr_sdram_mc_data *drvdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) const struct altr_sdram_prv_data *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct regmap *mc_vbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct dimm_info *dimm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) u32 read_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) int irq, irq2, res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) unsigned long mem_size, irqflags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) id = of_match_device(altr_sdram_ctrl_of_match, &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (!id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /* Grab the register range from the sdr controller in device tree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) mc_vbase = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) "altr,sdr-syscon");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (IS_ERR(mc_vbase)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) edac_printk(KERN_ERR, EDAC_MC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) "regmap for altr,sdr-syscon lookup failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /* Check specific dependencies for the module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) priv = of_match_node(altr_sdram_ctrl_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) pdev->dev.of_node)->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /* Validate the SDRAM controller has ECC enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (regmap_read(mc_vbase, priv->ecc_ctrl_offset, &read_reg) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) ((read_reg & priv->ecc_ctl_en_mask) != priv->ecc_ctl_en_mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) edac_printk(KERN_ERR, EDAC_MC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) "No ECC/ECC disabled [0x%08X]\n", read_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /* Grab memory size from device tree. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) mem_size = get_total_mem();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (!mem_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) edac_printk(KERN_ERR, EDAC_MC, "Unable to calculate memory size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /* Ensure the SDRAM Interrupt is disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (regmap_update_bits(mc_vbase, priv->ecc_irq_en_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) priv->ecc_irq_en_mask, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) edac_printk(KERN_ERR, EDAC_MC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) "Error disabling SDRAM ECC IRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) /* Toggle to clear the SDRAM Error count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (regmap_update_bits(mc_vbase, priv->ecc_cnt_rst_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) priv->ecc_cnt_rst_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) priv->ecc_cnt_rst_mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) edac_printk(KERN_ERR, EDAC_MC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) "Error clearing SDRAM ECC count\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (regmap_update_bits(mc_vbase, priv->ecc_cnt_rst_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) priv->ecc_cnt_rst_mask, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) edac_printk(KERN_ERR, EDAC_MC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) "Error clearing SDRAM ECC count\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (irq < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) edac_printk(KERN_ERR, EDAC_MC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) "No irq %d in DT\n", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* Arria10 has a 2nd IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) irq2 = platform_get_irq(pdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) layers[0].size = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) layers[0].is_virt_csrow = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) layers[1].type = EDAC_MC_LAYER_CHANNEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) layers[1].size = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) layers[1].is_virt_csrow = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) sizeof(struct altr_sdram_mc_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (!mci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) mci->pdev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) drvdata = mci->pvt_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) drvdata->mc_vbase = mc_vbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) drvdata->data = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) platform_set_drvdata(pdev, mci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) edac_printk(KERN_ERR, EDAC_MC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) "Unable to get managed device resource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) res = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) mci->mtype_cap = MEM_FLAG_DDR3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) mci->edac_cap = EDAC_FLAG_SECDED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) mci->mod_name = EDAC_MOD_STR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) mci->ctl_name = dev_name(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) mci->scrub_mode = SCRUB_SW_SRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) mci->dev_name = dev_name(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) dimm = *mci->dimms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) dimm->nr_pages = ((mem_size - 1) >> PAGE_SHIFT) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) dimm->grain = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) dimm->dtype = DEV_X8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) dimm->mtype = MEM_DDR3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) dimm->edac_mode = EDAC_SECDED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) res = edac_mc_add_mc(mci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (res < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) /* Only the Arria10 has separate IRQs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (of_machine_is_compatible("altr,socfpga-arria10")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) /* Arria10 specific initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) res = a10_init(mc_vbase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (res < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) goto err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) res = devm_request_irq(&pdev->dev, irq2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) altr_sdram_mc_err_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) IRQF_SHARED, dev_name(&pdev->dev), mci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (res < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) edac_mc_printk(mci, KERN_ERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) "Unable to request irq %d\n", irq2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) res = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) goto err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) res = a10_unmask_irq(pdev, A10_DDR0_IRQ_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (res < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) goto err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) irqflags = IRQF_SHARED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) res = devm_request_irq(&pdev->dev, irq, altr_sdram_mc_err_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) irqflags, dev_name(&pdev->dev), mci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (res < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) edac_mc_printk(mci, KERN_ERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) "Unable to request irq %d\n", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) res = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) goto err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) /* Infrastructure ready - enable the IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (regmap_update_bits(drvdata->mc_vbase, priv->ecc_irq_en_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) priv->ecc_irq_en_mask, priv->ecc_irq_en_mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) edac_mc_printk(mci, KERN_ERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) "Error enabling SDRAM ECC IRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) res = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) goto err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) altr_sdr_mc_create_debugfs_nodes(mci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) devres_close_group(&pdev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) err2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) edac_mc_del_mc(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) devres_release_group(&pdev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) edac_mc_free(mci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) edac_printk(KERN_ERR, EDAC_MC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) "EDAC Probe Failed; Error %d\n", res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) static int altr_sdram_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct mem_ctl_info *mci = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) edac_mc_del_mc(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) edac_mc_free(mci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) platform_set_drvdata(pdev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * If you want to suspend, need to disable EDAC by removing it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) * from the device tree or defconfig.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) static int altr_sdram_prepare(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) pr_err("Suspend not allowed when EDAC is enabled.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static const struct dev_pm_ops altr_sdram_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) .prepare = altr_sdram_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) static struct platform_driver altr_sdram_edac_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) .probe = altr_sdram_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) .remove = altr_sdram_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) .name = "altr_sdram_edac",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) .pm = &altr_sdram_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) .of_match_table = altr_sdram_ctrl_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) module_platform_driver(altr_sdram_edac_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) #endif /* CONFIG_EDAC_ALTERA_SDRAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) /************************* EDAC Parent Probe *************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) static const struct of_device_id altr_edac_device_of_match[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) static const struct of_device_id altr_edac_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) { .compatible = "altr,socfpga-ecc-manager" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) MODULE_DEVICE_TABLE(of, altr_edac_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) static int altr_edac_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) of_platform_populate(pdev->dev.of_node, altr_edac_device_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) NULL, &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) static struct platform_driver altr_edac_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) .probe = altr_edac_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) .name = "socfpga_ecc_manager",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) .of_match_table = altr_edac_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) module_platform_driver(altr_edac_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) /************************* EDAC Device Functions *************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) * EDAC Device Functions (shared between various IPs).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * The discrete memories use the EDAC Device framework. The probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * and error handling functions are very similar between memories
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * so they are shared. The memory allocation and freeing for EDAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) * trigger testing are different for each memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) static const struct edac_device_prv_data ocramecc_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static const struct edac_device_prv_data l2ecc_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) static const struct edac_device_prv_data a10_ocramecc_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) static const struct edac_device_prv_data a10_l2ecc_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) static irqreturn_t altr_edac_device_handler(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) irqreturn_t ret_value = IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) struct edac_device_ctl_info *dci = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) struct altr_edac_device_dev *drvdata = dci->pvt_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) const struct edac_device_prv_data *priv = drvdata->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (irq == drvdata->sb_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (priv->ce_clear_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) writel(priv->ce_clear_mask, drvdata->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) edac_device_handle_ce(dci, 0, 0, drvdata->edac_dev_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) ret_value = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) } else if (irq == drvdata->db_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (priv->ue_clear_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) writel(priv->ue_clear_mask, drvdata->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) edac_device_handle_ue(dci, 0, 0, drvdata->edac_dev_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) panic("\nEDAC:ECC_DEVICE[Uncorrectable errors]\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) ret_value = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return ret_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) static ssize_t altr_edac_device_trig(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) const char __user *user_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) u32 *ptemp, i, error_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) u8 trig_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) struct edac_device_ctl_info *edac_dci = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct altr_edac_device_dev *drvdata = edac_dci->pvt_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) const struct edac_device_prv_data *priv = drvdata->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) void *generic_ptr = edac_dci->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (!user_buf || get_user(trig_type, user_buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (!priv->alloc_mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) * Note that generic_ptr is initialized to the device * but in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) * some alloc_functions, this is overridden and returns data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) ptemp = priv->alloc_mem(priv->trig_alloc_sz, &generic_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (!ptemp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) edac_printk(KERN_ERR, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) "Inject: Buffer Allocation error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (trig_type == ALTR_UE_TRIGGER_CHAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) error_mask = priv->ue_set_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) error_mask = priv->ce_set_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) edac_printk(KERN_ALERT, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) "Trigger Error Mask (0x%X)\n", error_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /* write ECC corrupted data out. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) for (i = 0; i < (priv->trig_alloc_sz / sizeof(*ptemp)); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) /* Read data so we're in the correct state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (READ_ONCE(ptemp[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) result = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) /* Toggle Error bit (it is latched), leave ECC enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) writel(error_mask, (drvdata->base + priv->set_err_ofst));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) writel(priv->ecc_enable_mask, (drvdata->base +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) priv->set_err_ofst));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) ptemp[i] = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) /* Ensure it has been written out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) edac_printk(KERN_ERR, EDAC_DEVICE, "Mem Not Cleared\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) /* Read out written data. ECC error caused here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) for (i = 0; i < ALTR_TRIGGER_READ_WRD_CNT; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (READ_ONCE(ptemp[i]) != i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) edac_printk(KERN_ERR, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) "Read doesn't match written data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (priv->free_mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) priv->free_mem(ptemp, priv->trig_alloc_sz, generic_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) static const struct file_operations altr_edac_device_inject_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) .open = simple_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) .write = altr_edac_device_trig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) .llseek = generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) static ssize_t altr_edac_a10_device_trig(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) const char __user *user_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) size_t count, loff_t *ppos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) static const struct file_operations altr_edac_a10_device_inject_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) .open = simple_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) .write = altr_edac_a10_device_trig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) .llseek = generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) static ssize_t altr_edac_a10_device_trig2(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) const char __user *user_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) size_t count, loff_t *ppos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) static const struct file_operations altr_edac_a10_device_inject2_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) .open = simple_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) .write = altr_edac_a10_device_trig2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) .llseek = generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) static void altr_create_edacdev_dbgfs(struct edac_device_ctl_info *edac_dci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) const struct edac_device_prv_data *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) struct altr_edac_device_dev *drvdata = edac_dci->pvt_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (!IS_ENABLED(CONFIG_EDAC_DEBUG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) drvdata->debugfs_dir = edac_debugfs_create_dir(drvdata->edac_dev_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (!drvdata->debugfs_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (!edac_debugfs_create_file("altr_trigger", S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) drvdata->debugfs_dir, edac_dci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) priv->inject_fops))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) debugfs_remove_recursive(drvdata->debugfs_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) static const struct of_device_id altr_edac_device_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) #ifdef CONFIG_EDAC_ALTERA_L2C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) { .compatible = "altr,socfpga-l2-ecc", .data = &l2ecc_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) #ifdef CONFIG_EDAC_ALTERA_OCRAM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) { .compatible = "altr,socfpga-ocram-ecc", .data = &ocramecc_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) MODULE_DEVICE_TABLE(of, altr_edac_device_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) * altr_edac_device_probe()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) * This is a generic EDAC device driver that will support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) * various Altera memory devices such as the L2 cache ECC and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) * OCRAM ECC as well as the memories for other peripherals.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) * Module specific initialization is done by passing the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) * function index in the device tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) static int altr_edac_device_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) struct edac_device_ctl_info *dci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) struct altr_edac_device_dev *drvdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) struct resource *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) int res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) struct device_node *np = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) char *ecc_name = (char *)np->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static int dev_instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) edac_printk(KERN_ERR, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) "Unable to open devm\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) if (!r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) edac_printk(KERN_ERR, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) "Unable to get mem resource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) res = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (!devm_request_mem_region(&pdev->dev, r->start, resource_size(r),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) dev_name(&pdev->dev))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) edac_printk(KERN_ERR, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) "%s:Error requesting mem region\n", ecc_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) res = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) dci = edac_device_alloc_ctl_info(sizeof(*drvdata), ecc_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 1, ecc_name, 1, 0, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) dev_instance++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (!dci) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) edac_printk(KERN_ERR, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) "%s: Unable to allocate EDAC device\n", ecc_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) res = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) drvdata = dci->pvt_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) dci->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) platform_set_drvdata(pdev, dci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) drvdata->edac_dev_name = ecc_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) drvdata->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) if (!drvdata->base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) res = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) goto fail1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) /* Get driver specific data for this EDAC device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) drvdata->data = of_match_node(altr_edac_device_of_match, np)->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) /* Check specific dependencies for the module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) if (drvdata->data->setup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) res = drvdata->data->setup(drvdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) goto fail1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) drvdata->sb_irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) res = devm_request_irq(&pdev->dev, drvdata->sb_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) altr_edac_device_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 0, dev_name(&pdev->dev), dci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) goto fail1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) drvdata->db_irq = platform_get_irq(pdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) res = devm_request_irq(&pdev->dev, drvdata->db_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) altr_edac_device_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 0, dev_name(&pdev->dev), dci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) goto fail1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) dci->mod_name = "Altera ECC Manager";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) dci->dev_name = drvdata->edac_dev_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) res = edac_device_add_device(dci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) goto fail1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) altr_create_edacdev_dbgfs(dci, drvdata->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) devres_close_group(&pdev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) fail1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) edac_device_free_ctl_info(dci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) devres_release_group(&pdev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) edac_printk(KERN_ERR, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) "%s:Error setting up EDAC device: %d\n", ecc_name, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) static int altr_edac_device_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) struct edac_device_ctl_info *dci = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) struct altr_edac_device_dev *drvdata = dci->pvt_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) debugfs_remove_recursive(drvdata->debugfs_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) edac_device_del_device(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) edac_device_free_ctl_info(dci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) static struct platform_driver altr_edac_device_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) .probe = altr_edac_device_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) .remove = altr_edac_device_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) .name = "altr_edac_device",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) .of_match_table = altr_edac_device_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) module_platform_driver(altr_edac_device_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) /******************* Arria10 Device ECC Shared Functions *****************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) * Test for memory's ECC dependencies upon entry because platform specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) * startup should have initialized the memory and enabled the ECC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) * Can't turn on ECC here because accessing un-initialized memory will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * cause CE/UE errors possibly causing an ABORT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) static int __maybe_unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) altr_check_ecc_deps(struct altr_edac_device_dev *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) void __iomem *base = device->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) const struct edac_device_prv_data *prv = device->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) if (readl(base + prv->ecc_en_ofst) & prv->ecc_enable_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) edac_printk(KERN_ERR, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) "%s: No ECC present or ECC disabled.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) device->edac_dev_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) static irqreturn_t __maybe_unused altr_edac_a10_ecc_irq(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) struct altr_edac_device_dev *dci = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) void __iomem *base = dci->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (irq == dci->sb_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) writel(ALTR_A10_ECC_SERRPENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) base + ALTR_A10_ECC_INTSTAT_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) edac_device_handle_ce(dci->edac_dev, 0, 0, dci->edac_dev_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) } else if (irq == dci->db_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) writel(ALTR_A10_ECC_DERRPENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) base + ALTR_A10_ECC_INTSTAT_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) edac_device_handle_ue(dci->edac_dev, 0, 0, dci->edac_dev_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (dci->data->panic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) panic("\nEDAC:ECC_DEVICE[Uncorrectable errors]\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) /******************* Arria10 Memory Buffer Functions *********************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) static inline int a10_get_irq_mask(struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) const u32 *handle = of_get_property(np, "interrupts", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (!handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) irq = be32_to_cpup(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) return irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) static inline void ecc_set_bits(u32 bit_mask, void __iomem *ioaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) u32 value = readl(ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) value |= bit_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) writel(value, ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) static inline void ecc_clear_bits(u32 bit_mask, void __iomem *ioaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) u32 value = readl(ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) value &= ~bit_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) writel(value, ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) static inline int ecc_test_bits(u32 bit_mask, void __iomem *ioaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) u32 value = readl(ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) return (value & bit_mask) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) * This function uses the memory initialization block in the Arria10 ECC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) * controller to initialize/clear the entire memory data and ECC data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) static int __maybe_unused altr_init_memory_port(void __iomem *ioaddr, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) int limit = ALTR_A10_ECC_INIT_WATCHDOG_10US;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) u32 init_mask, stat_mask, clear_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) init_mask = ALTR_A10_ECC_INITB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) stat_mask = ALTR_A10_ECC_INITCOMPLETEB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) clear_mask = ALTR_A10_ECC_ERRPENB_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) init_mask = ALTR_A10_ECC_INITA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) stat_mask = ALTR_A10_ECC_INITCOMPLETEA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) clear_mask = ALTR_A10_ECC_ERRPENA_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) ecc_set_bits(init_mask, (ioaddr + ALTR_A10_ECC_CTRL_OFST));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) while (limit--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) if (ecc_test_bits(stat_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) (ioaddr + ALTR_A10_ECC_INITSTAT_OFST)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (limit < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) /* Clear any pending ECC interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) writel(clear_mask, (ioaddr + ALTR_A10_ECC_INTSTAT_OFST));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) static __init int __maybe_unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) altr_init_a10_ecc_block(struct device_node *np, u32 irq_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) u32 ecc_ctrl_en_mask, bool dual_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) void __iomem *ecc_block_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) struct regmap *ecc_mgr_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) char *ecc_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) struct device_node *np_eccmgr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) ecc_name = (char *)np->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) /* Get the ECC Manager - parent of the device EDACs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) np_eccmgr = of_get_parent(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) ecc_mgr_map =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) altr_sysmgr_regmap_lookup_by_phandle(np_eccmgr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) "altr,sysmgr-syscon");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) of_node_put(np_eccmgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (IS_ERR(ecc_mgr_map)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) edac_printk(KERN_ERR, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) "Unable to get syscon altr,sysmgr-syscon\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) /* Map the ECC Block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) ecc_block_base = of_iomap(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) if (!ecc_block_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) edac_printk(KERN_ERR, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) "Unable to map %s ECC block\n", ecc_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) /* Disable ECC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) regmap_write(ecc_mgr_map, A10_SYSMGR_ECC_INTMASK_SET_OFST, irq_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) writel(ALTR_A10_ECC_SERRINTEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) (ecc_block_base + ALTR_A10_ECC_ERRINTENR_OFST));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) ecc_clear_bits(ecc_ctrl_en_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) (ecc_block_base + ALTR_A10_ECC_CTRL_OFST));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) /* Ensure all writes complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) /* Use HW initialization block to initialize memory for ECC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) ret = altr_init_memory_port(ecc_block_base, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) edac_printk(KERN_ERR, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) "ECC: cannot init %s PORTA memory\n", ecc_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) if (dual_port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) ret = altr_init_memory_port(ecc_block_base, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) edac_printk(KERN_ERR, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) "ECC: cannot init %s PORTB memory\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) ecc_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) /* Interrupt mode set to every SBERR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) regmap_write(ecc_mgr_map, ALTR_A10_ECC_INTMODE_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) ALTR_A10_ECC_INTMODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) /* Enable ECC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) ecc_set_bits(ecc_ctrl_en_mask, (ecc_block_base +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) ALTR_A10_ECC_CTRL_OFST));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) writel(ALTR_A10_ECC_SERRINTEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) (ecc_block_base + ALTR_A10_ECC_ERRINTENS_OFST));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) regmap_write(ecc_mgr_map, A10_SYSMGR_ECC_INTMASK_CLR_OFST, irq_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) /* Ensure all writes complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) iounmap(ecc_block_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) static int validate_parent_available(struct device_node *np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) static const struct of_device_id altr_edac_a10_device_of_match[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) static int __init __maybe_unused altr_init_a10_ecc_device_type(char *compat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) struct device_node *child, *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) np = of_find_compatible_node(NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) "altr,socfpga-a10-ecc-manager");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) if (!np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) edac_printk(KERN_ERR, EDAC_DEVICE, "ECC Manager not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) for_each_child_of_node(np, child) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) const struct of_device_id *pdev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) const struct edac_device_prv_data *prv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) if (!of_device_is_available(child))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) if (!of_device_is_compatible(child, compat))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (validate_parent_available(child))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) irq = a10_get_irq_mask(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) if (irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) /* Get matching node and check for valid result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) pdev_id = of_match_node(altr_edac_a10_device_of_match, child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (IS_ERR_OR_NULL(pdev_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) /* Validate private data pointer before dereferencing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) prv = pdev_id->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) if (!prv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) altr_init_a10_ecc_block(child, BIT(irq),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) prv->ecc_enable_mask, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) /*********************** SDRAM EDAC Device Functions *********************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) #ifdef CONFIG_EDAC_ALTERA_SDRAM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) static const struct edac_device_prv_data s10_sdramecc_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) .setup = altr_check_ecc_deps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) .ce_clear_mask = ALTR_S10_ECC_SERRPENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) .ue_clear_mask = ALTR_S10_ECC_DERRPENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) .ecc_enable_mask = ALTR_S10_ECC_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) .ecc_en_ofst = ALTR_S10_ECC_CTRL_SDRAM_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) .ce_set_mask = ALTR_S10_ECC_TSERRA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) .ue_set_mask = ALTR_S10_ECC_TDERRA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) .set_err_ofst = ALTR_S10_ECC_INTTEST_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) .ecc_irq_handler = altr_edac_a10_ecc_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) .inject_fops = &altr_edac_a10_device_inject_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) #endif /* CONFIG_EDAC_ALTERA_SDRAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) /*********************** OCRAM EDAC Device Functions *********************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) #ifdef CONFIG_EDAC_ALTERA_OCRAM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) static void *ocram_alloc_mem(size_t size, void **other)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) struct gen_pool *gp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) void *sram_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) np = of_find_compatible_node(NULL, NULL, "altr,socfpga-ocram-ecc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) gp = of_gen_pool_get(np, "iram", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) if (!gp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) sram_addr = (void *)gen_pool_alloc(gp, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) if (!sram_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) memset(sram_addr, 0, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) /* Ensure data is written out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) /* Remember this handle for freeing later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) *other = gp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) return sram_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) static void ocram_free_mem(void *p, size_t size, void *other)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) gen_pool_free((struct gen_pool *)other, (unsigned long)p, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) static const struct edac_device_prv_data ocramecc_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) .setup = altr_check_ecc_deps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) .ce_clear_mask = (ALTR_OCR_ECC_EN | ALTR_OCR_ECC_SERR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) .ue_clear_mask = (ALTR_OCR_ECC_EN | ALTR_OCR_ECC_DERR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) .alloc_mem = ocram_alloc_mem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) .free_mem = ocram_free_mem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) .ecc_enable_mask = ALTR_OCR_ECC_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) .ecc_en_ofst = ALTR_OCR_ECC_REG_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) .ce_set_mask = (ALTR_OCR_ECC_EN | ALTR_OCR_ECC_INJS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) .ue_set_mask = (ALTR_OCR_ECC_EN | ALTR_OCR_ECC_INJD),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) .set_err_ofst = ALTR_OCR_ECC_REG_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) .trig_alloc_sz = ALTR_TRIG_OCRAM_BYTE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) .inject_fops = &altr_edac_device_inject_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) static int __maybe_unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) altr_check_ocram_deps_init(struct altr_edac_device_dev *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) void __iomem *base = device->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) ret = altr_check_ecc_deps(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) /* Verify OCRAM has been initialized */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) if (!ecc_test_bits(ALTR_A10_ECC_INITCOMPLETEA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) (base + ALTR_A10_ECC_INITSTAT_OFST)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) /* Enable IRQ on Single Bit Error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) writel(ALTR_A10_ECC_SERRINTEN, (base + ALTR_A10_ECC_ERRINTENS_OFST));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) /* Ensure all writes complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) static const struct edac_device_prv_data a10_ocramecc_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) .setup = altr_check_ocram_deps_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) .ce_clear_mask = ALTR_A10_ECC_SERRPENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) .ue_clear_mask = ALTR_A10_ECC_DERRPENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) .irq_status_mask = A10_SYSMGR_ECC_INTSTAT_OCRAM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) .ecc_enable_mask = ALTR_A10_OCRAM_ECC_EN_CTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) .ecc_en_ofst = ALTR_A10_ECC_CTRL_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) .ce_set_mask = ALTR_A10_ECC_TSERRA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) .ue_set_mask = ALTR_A10_ECC_TDERRA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) .set_err_ofst = ALTR_A10_ECC_INTTEST_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) .ecc_irq_handler = altr_edac_a10_ecc_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) .inject_fops = &altr_edac_a10_device_inject2_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) * OCRAM panic on uncorrectable error because sleep/resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) * functions and FPGA contents are stored in OCRAM. Prefer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) * a kernel panic over executing/loading corrupted data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) .panic = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) #endif /* CONFIG_EDAC_ALTERA_OCRAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) /********************* L2 Cache EDAC Device Functions ********************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) #ifdef CONFIG_EDAC_ALTERA_L2C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) static void *l2_alloc_mem(size_t size, void **other)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) struct device *dev = *other;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) void *ptemp = devm_kzalloc(dev, size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) if (!ptemp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) /* Make sure everything is written out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) * Clean all cache levels up to LoC (includes L2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) * This ensures the corrupted data is written into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) * L2 cache for readback test (which causes ECC error).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) flush_cache_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) return ptemp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) static void l2_free_mem(void *p, size_t size, void *other)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) struct device *dev = other;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) if (dev && p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) devm_kfree(dev, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) * altr_l2_check_deps()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) * Test for L2 cache ECC dependencies upon entry because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) * platform specific startup should have initialized the L2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) * memory and enabled the ECC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) * Bail if ECC is not enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) * Note that L2 Cache Enable is forced at build time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) static int altr_l2_check_deps(struct altr_edac_device_dev *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) void __iomem *base = device->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) const struct edac_device_prv_data *prv = device->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) if ((readl(base) & prv->ecc_enable_mask) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) prv->ecc_enable_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) edac_printk(KERN_ERR, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) "L2: No ECC present, or ECC disabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) static irqreturn_t altr_edac_a10_l2_irq(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) struct altr_edac_device_dev *dci = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) if (irq == dci->sb_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) regmap_write(dci->edac->ecc_mgr_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) A10_SYSGMR_MPU_CLEAR_L2_ECC_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) A10_SYSGMR_MPU_CLEAR_L2_ECC_SB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) edac_device_handle_ce(dci->edac_dev, 0, 0, dci->edac_dev_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) } else if (irq == dci->db_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) regmap_write(dci->edac->ecc_mgr_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) A10_SYSGMR_MPU_CLEAR_L2_ECC_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) A10_SYSGMR_MPU_CLEAR_L2_ECC_MB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) edac_device_handle_ue(dci->edac_dev, 0, 0, dci->edac_dev_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) panic("\nEDAC:ECC_DEVICE[Uncorrectable errors]\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) static const struct edac_device_prv_data l2ecc_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) .setup = altr_l2_check_deps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) .ce_clear_mask = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) .ue_clear_mask = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) .alloc_mem = l2_alloc_mem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) .free_mem = l2_free_mem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) .ecc_enable_mask = ALTR_L2_ECC_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) .ce_set_mask = (ALTR_L2_ECC_EN | ALTR_L2_ECC_INJS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) .ue_set_mask = (ALTR_L2_ECC_EN | ALTR_L2_ECC_INJD),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) .set_err_ofst = ALTR_L2_ECC_REG_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) .trig_alloc_sz = ALTR_TRIG_L2C_BYTE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) .inject_fops = &altr_edac_device_inject_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) static const struct edac_device_prv_data a10_l2ecc_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) .setup = altr_l2_check_deps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) .ce_clear_mask = ALTR_A10_L2_ECC_SERR_CLR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) .ue_clear_mask = ALTR_A10_L2_ECC_MERR_CLR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) .irq_status_mask = A10_SYSMGR_ECC_INTSTAT_L2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) .alloc_mem = l2_alloc_mem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) .free_mem = l2_free_mem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) .ecc_enable_mask = ALTR_A10_L2_ECC_EN_CTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) .ce_set_mask = ALTR_A10_L2_ECC_CE_INJ_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) .ue_set_mask = ALTR_A10_L2_ECC_UE_INJ_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) .set_err_ofst = ALTR_A10_L2_ECC_INJ_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) .ecc_irq_handler = altr_edac_a10_l2_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) .trig_alloc_sz = ALTR_TRIG_L2C_BYTE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) .inject_fops = &altr_edac_device_inject_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) #endif /* CONFIG_EDAC_ALTERA_L2C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) /********************* Ethernet Device Functions ********************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) #ifdef CONFIG_EDAC_ALTERA_ETHERNET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) static int __init socfpga_init_ethernet_ecc(struct altr_edac_device_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) ret = altr_init_a10_ecc_device_type("altr,socfpga-eth-mac-ecc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) return altr_check_ecc_deps(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) static const struct edac_device_prv_data a10_enetecc_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) .setup = socfpga_init_ethernet_ecc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) .ce_clear_mask = ALTR_A10_ECC_SERRPENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) .ue_clear_mask = ALTR_A10_ECC_DERRPENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) .ecc_enable_mask = ALTR_A10_COMMON_ECC_EN_CTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) .ecc_en_ofst = ALTR_A10_ECC_CTRL_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) .ce_set_mask = ALTR_A10_ECC_TSERRA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) .ue_set_mask = ALTR_A10_ECC_TDERRA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) .set_err_ofst = ALTR_A10_ECC_INTTEST_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) .ecc_irq_handler = altr_edac_a10_ecc_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) .inject_fops = &altr_edac_a10_device_inject2_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) #endif /* CONFIG_EDAC_ALTERA_ETHERNET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) /********************** NAND Device Functions **********************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) #ifdef CONFIG_EDAC_ALTERA_NAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) static int __init socfpga_init_nand_ecc(struct altr_edac_device_dev *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) ret = altr_init_a10_ecc_device_type("altr,socfpga-nand-ecc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) return altr_check_ecc_deps(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) static const struct edac_device_prv_data a10_nandecc_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) .setup = socfpga_init_nand_ecc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) .ce_clear_mask = ALTR_A10_ECC_SERRPENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) .ue_clear_mask = ALTR_A10_ECC_DERRPENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) .ecc_enable_mask = ALTR_A10_COMMON_ECC_EN_CTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) .ecc_en_ofst = ALTR_A10_ECC_CTRL_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) .ce_set_mask = ALTR_A10_ECC_TSERRA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) .ue_set_mask = ALTR_A10_ECC_TDERRA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) .set_err_ofst = ALTR_A10_ECC_INTTEST_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) .ecc_irq_handler = altr_edac_a10_ecc_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) .inject_fops = &altr_edac_a10_device_inject_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) #endif /* CONFIG_EDAC_ALTERA_NAND */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) /********************** DMA Device Functions **********************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) #ifdef CONFIG_EDAC_ALTERA_DMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) static int __init socfpga_init_dma_ecc(struct altr_edac_device_dev *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) ret = altr_init_a10_ecc_device_type("altr,socfpga-dma-ecc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) return altr_check_ecc_deps(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) static const struct edac_device_prv_data a10_dmaecc_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) .setup = socfpga_init_dma_ecc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) .ce_clear_mask = ALTR_A10_ECC_SERRPENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) .ue_clear_mask = ALTR_A10_ECC_DERRPENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) .ecc_enable_mask = ALTR_A10_COMMON_ECC_EN_CTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) .ecc_en_ofst = ALTR_A10_ECC_CTRL_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) .ce_set_mask = ALTR_A10_ECC_TSERRA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) .ue_set_mask = ALTR_A10_ECC_TDERRA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) .set_err_ofst = ALTR_A10_ECC_INTTEST_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) .ecc_irq_handler = altr_edac_a10_ecc_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) .inject_fops = &altr_edac_a10_device_inject_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) #endif /* CONFIG_EDAC_ALTERA_DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) /********************** USB Device Functions **********************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) #ifdef CONFIG_EDAC_ALTERA_USB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) static int __init socfpga_init_usb_ecc(struct altr_edac_device_dev *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) ret = altr_init_a10_ecc_device_type("altr,socfpga-usb-ecc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) return altr_check_ecc_deps(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) static const struct edac_device_prv_data a10_usbecc_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) .setup = socfpga_init_usb_ecc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) .ce_clear_mask = ALTR_A10_ECC_SERRPENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) .ue_clear_mask = ALTR_A10_ECC_DERRPENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) .ecc_enable_mask = ALTR_A10_COMMON_ECC_EN_CTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) .ecc_en_ofst = ALTR_A10_ECC_CTRL_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) .ce_set_mask = ALTR_A10_ECC_TSERRA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) .ue_set_mask = ALTR_A10_ECC_TDERRA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) .set_err_ofst = ALTR_A10_ECC_INTTEST_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) .ecc_irq_handler = altr_edac_a10_ecc_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) .inject_fops = &altr_edac_a10_device_inject2_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) #endif /* CONFIG_EDAC_ALTERA_USB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) /********************** QSPI Device Functions **********************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) #ifdef CONFIG_EDAC_ALTERA_QSPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) static int __init socfpga_init_qspi_ecc(struct altr_edac_device_dev *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) ret = altr_init_a10_ecc_device_type("altr,socfpga-qspi-ecc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) return altr_check_ecc_deps(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) static const struct edac_device_prv_data a10_qspiecc_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) .setup = socfpga_init_qspi_ecc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) .ce_clear_mask = ALTR_A10_ECC_SERRPENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) .ue_clear_mask = ALTR_A10_ECC_DERRPENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) .ecc_enable_mask = ALTR_A10_COMMON_ECC_EN_CTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) .ecc_en_ofst = ALTR_A10_ECC_CTRL_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) .ce_set_mask = ALTR_A10_ECC_TSERRA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) .ue_set_mask = ALTR_A10_ECC_TDERRA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) .set_err_ofst = ALTR_A10_ECC_INTTEST_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) .ecc_irq_handler = altr_edac_a10_ecc_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) .inject_fops = &altr_edac_a10_device_inject_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) #endif /* CONFIG_EDAC_ALTERA_QSPI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) /********************* SDMMC Device Functions **********************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) #ifdef CONFIG_EDAC_ALTERA_SDMMC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) static const struct edac_device_prv_data a10_sdmmceccb_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) static int altr_portb_setup(struct altr_edac_device_dev *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) struct edac_device_ctl_info *dci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) struct altr_edac_device_dev *altdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) char *ecc_name = "sdmmcb-ecc";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) int edac_idx, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) const struct edac_device_prv_data *prv = &a10_sdmmceccb_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) rc = altr_check_ecc_deps(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) np = of_find_compatible_node(NULL, NULL, "altr,socfpga-sdmmc-ecc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) if (!np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) edac_printk(KERN_WARNING, EDAC_DEVICE, "SDMMC node not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) /* Create the PortB EDAC device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) edac_idx = edac_device_alloc_index();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) dci = edac_device_alloc_ctl_info(sizeof(*altdev), ecc_name, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) ecc_name, 1, 0, NULL, 0, edac_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) if (!dci) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) edac_printk(KERN_ERR, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) "%s: Unable to allocate PortB EDAC device\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) ecc_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) /* Initialize the PortB EDAC device structure from PortA structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) altdev = dci->pvt_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) *altdev = *device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) if (!devres_open_group(&altdev->ddev, altr_portb_setup, GFP_KERNEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) /* Update PortB specific values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) altdev->edac_dev_name = ecc_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) altdev->edac_idx = edac_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) altdev->edac_dev = dci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) altdev->data = prv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) dci->dev = &altdev->ddev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) dci->ctl_name = "Altera ECC Manager";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) dci->mod_name = ecc_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) dci->dev_name = ecc_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) /* Update the PortB IRQs - A10 has 4, S10 has 2, Index accordingly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) #ifdef CONFIG_ARCH_STRATIX10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) altdev->sb_irq = irq_of_parse_and_map(np, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) altdev->sb_irq = irq_of_parse_and_map(np, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) if (!altdev->sb_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) edac_printk(KERN_ERR, EDAC_DEVICE, "Error PortB SBIRQ alloc\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) goto err_release_group_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) rc = devm_request_irq(&altdev->ddev, altdev->sb_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) prv->ecc_irq_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) ecc_name, altdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) edac_printk(KERN_ERR, EDAC_DEVICE, "PortB SBERR IRQ error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) goto err_release_group_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) #ifdef CONFIG_ARCH_STRATIX10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) /* Use IRQ to determine SError origin instead of assigning IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) rc = of_property_read_u32_index(np, "interrupts", 1, &altdev->db_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) edac_printk(KERN_ERR, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) "Error PortB DBIRQ alloc\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) goto err_release_group_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) altdev->db_irq = irq_of_parse_and_map(np, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) if (!altdev->db_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) edac_printk(KERN_ERR, EDAC_DEVICE, "Error PortB DBIRQ alloc\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) goto err_release_group_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) rc = devm_request_irq(&altdev->ddev, altdev->db_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) prv->ecc_irq_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) ecc_name, altdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) edac_printk(KERN_ERR, EDAC_DEVICE, "PortB DBERR IRQ error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) goto err_release_group_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) rc = edac_device_add_device(dci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) edac_printk(KERN_ERR, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) "edac_device_add_device portB failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) goto err_release_group_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) altr_create_edacdev_dbgfs(dci, prv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) list_add(&altdev->next, &altdev->edac->a10_ecc_devices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) devres_remove_group(&altdev->ddev, altr_portb_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) err_release_group_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) edac_device_free_ctl_info(dci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) devres_release_group(&altdev->ddev, altr_portb_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) edac_printk(KERN_ERR, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) "%s:Error setting up EDAC device: %d\n", ecc_name, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) static int __init socfpga_init_sdmmc_ecc(struct altr_edac_device_dev *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) int rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) struct device_node *child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) child = of_find_compatible_node(NULL, NULL, "altr,socfpga-sdmmc-ecc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) if (!child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) if (!of_device_is_available(child))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) if (validate_parent_available(child))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) /* Init portB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) rc = altr_init_a10_ecc_block(child, ALTR_A10_SDMMC_IRQ_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) a10_sdmmceccb_data.ecc_enable_mask, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) /* Setup portB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) return altr_portb_setup(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) of_node_put(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) static irqreturn_t altr_edac_a10_ecc_irq_portb(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) struct altr_edac_device_dev *ad = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) void __iomem *base = ad->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) const struct edac_device_prv_data *priv = ad->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) if (irq == ad->sb_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) writel(priv->ce_clear_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) base + ALTR_A10_ECC_INTSTAT_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) edac_device_handle_ce(ad->edac_dev, 0, 0, ad->edac_dev_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) } else if (irq == ad->db_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) writel(priv->ue_clear_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) base + ALTR_A10_ECC_INTSTAT_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) edac_device_handle_ue(ad->edac_dev, 0, 0, ad->edac_dev_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) WARN_ONCE(1, "Unhandled IRQ%d on Port B.", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) static const struct edac_device_prv_data a10_sdmmcecca_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) .setup = socfpga_init_sdmmc_ecc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) .ce_clear_mask = ALTR_A10_ECC_SERRPENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) .ue_clear_mask = ALTR_A10_ECC_DERRPENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) .ecc_enable_mask = ALTR_A10_COMMON_ECC_EN_CTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) .ecc_en_ofst = ALTR_A10_ECC_CTRL_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) .ce_set_mask = ALTR_A10_ECC_SERRPENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) .ue_set_mask = ALTR_A10_ECC_DERRPENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) .set_err_ofst = ALTR_A10_ECC_INTTEST_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) .ecc_irq_handler = altr_edac_a10_ecc_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) .inject_fops = &altr_edac_a10_device_inject_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) static const struct edac_device_prv_data a10_sdmmceccb_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) .setup = socfpga_init_sdmmc_ecc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) .ce_clear_mask = ALTR_A10_ECC_SERRPENB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) .ue_clear_mask = ALTR_A10_ECC_DERRPENB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) .ecc_enable_mask = ALTR_A10_COMMON_ECC_EN_CTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) .ecc_en_ofst = ALTR_A10_ECC_CTRL_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) .ce_set_mask = ALTR_A10_ECC_TSERRB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) .ue_set_mask = ALTR_A10_ECC_TDERRB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) .set_err_ofst = ALTR_A10_ECC_INTTEST_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) .ecc_irq_handler = altr_edac_a10_ecc_irq_portb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) .inject_fops = &altr_edac_a10_device_inject_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) #endif /* CONFIG_EDAC_ALTERA_SDMMC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) /********************* Arria10 EDAC Device Functions *************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) static const struct of_device_id altr_edac_a10_device_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) #ifdef CONFIG_EDAC_ALTERA_L2C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) { .compatible = "altr,socfpga-a10-l2-ecc", .data = &a10_l2ecc_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) #ifdef CONFIG_EDAC_ALTERA_OCRAM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) { .compatible = "altr,socfpga-a10-ocram-ecc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) .data = &a10_ocramecc_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) #ifdef CONFIG_EDAC_ALTERA_ETHERNET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) { .compatible = "altr,socfpga-eth-mac-ecc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) .data = &a10_enetecc_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) #ifdef CONFIG_EDAC_ALTERA_NAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) { .compatible = "altr,socfpga-nand-ecc", .data = &a10_nandecc_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) #ifdef CONFIG_EDAC_ALTERA_DMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) { .compatible = "altr,socfpga-dma-ecc", .data = &a10_dmaecc_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) #ifdef CONFIG_EDAC_ALTERA_USB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) { .compatible = "altr,socfpga-usb-ecc", .data = &a10_usbecc_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) #ifdef CONFIG_EDAC_ALTERA_QSPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) { .compatible = "altr,socfpga-qspi-ecc", .data = &a10_qspiecc_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) #ifdef CONFIG_EDAC_ALTERA_SDMMC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) { .compatible = "altr,socfpga-sdmmc-ecc", .data = &a10_sdmmcecca_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) #ifdef CONFIG_EDAC_ALTERA_SDRAM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) { .compatible = "altr,sdram-edac-s10", .data = &s10_sdramecc_data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) MODULE_DEVICE_TABLE(of, altr_edac_a10_device_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) * The Arria10 EDAC Device Functions differ from the Cyclone5/Arria5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) * because 2 IRQs are shared among the all ECC peripherals. The ECC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) * manager manages the IRQs and the children.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) * Based on xgene_edac.c peripheral code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) static ssize_t altr_edac_a10_device_trig(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) const char __user *user_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) struct edac_device_ctl_info *edac_dci = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) struct altr_edac_device_dev *drvdata = edac_dci->pvt_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) const struct edac_device_prv_data *priv = drvdata->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) void __iomem *set_addr = (drvdata->base + priv->set_err_ofst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) u8 trig_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) if (!user_buf || get_user(trig_type, user_buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) if (trig_type == ALTR_UE_TRIGGER_CHAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) writel(priv->ue_set_mask, set_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) writel(priv->ce_set_mask, set_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) /* Ensure the interrupt test bits are set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) * The Stratix10 EDAC Error Injection Functions differ from Arria10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) * slightly. A few Arria10 peripherals can use this injection function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) * Inject the error into the memory and then readback to trigger the IRQ.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) static ssize_t altr_edac_a10_device_trig2(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) const char __user *user_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) struct edac_device_ctl_info *edac_dci = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) struct altr_edac_device_dev *drvdata = edac_dci->pvt_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) const struct edac_device_prv_data *priv = drvdata->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) void __iomem *set_addr = (drvdata->base + priv->set_err_ofst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) u8 trig_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) if (!user_buf || get_user(trig_type, user_buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) if (trig_type == ALTR_UE_TRIGGER_CHAR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) writel(priv->ue_set_mask, set_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) /* Setup read/write of 4 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) writel(ECC_WORD_WRITE, drvdata->base + ECC_BLK_DBYTECTRL_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) /* Setup Address to 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) writel(0, drvdata->base + ECC_BLK_ADDRESS_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) /* Setup accctrl to read & ecc & data override */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) writel(ECC_READ_EDOVR, drvdata->base + ECC_BLK_ACCCTRL_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) /* Kick it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) writel(ECC_XACT_KICK, drvdata->base + ECC_BLK_STARTACC_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) /* Setup write for single bit change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) writel(readl(drvdata->base + ECC_BLK_RDATA0_OFST) ^ 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) drvdata->base + ECC_BLK_WDATA0_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) writel(readl(drvdata->base + ECC_BLK_RDATA1_OFST),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) drvdata->base + ECC_BLK_WDATA1_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) writel(readl(drvdata->base + ECC_BLK_RDATA2_OFST),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) drvdata->base + ECC_BLK_WDATA2_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) writel(readl(drvdata->base + ECC_BLK_RDATA3_OFST),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) drvdata->base + ECC_BLK_WDATA3_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) /* Copy Read ECC to Write ECC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) writel(readl(drvdata->base + ECC_BLK_RECC0_OFST),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) drvdata->base + ECC_BLK_WECC0_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) writel(readl(drvdata->base + ECC_BLK_RECC1_OFST),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) drvdata->base + ECC_BLK_WECC1_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) /* Setup accctrl to write & ecc override & data override */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) writel(ECC_WRITE_EDOVR, drvdata->base + ECC_BLK_ACCCTRL_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) /* Kick it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) writel(ECC_XACT_KICK, drvdata->base + ECC_BLK_STARTACC_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) /* Setup accctrl to read & ecc overwrite & data overwrite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) writel(ECC_READ_EDOVR, drvdata->base + ECC_BLK_ACCCTRL_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) /* Kick it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) writel(ECC_XACT_KICK, drvdata->base + ECC_BLK_STARTACC_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) /* Ensure the interrupt test bits are set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) static void altr_edac_a10_irq_handler(struct irq_desc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) int dberr, bit, sm_offset, irq_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) struct altr_arria10_edac *edac = irq_desc_get_handler_data(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) struct irq_chip *chip = irq_desc_get_chip(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) int irq = irq_desc_get_irq(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) unsigned long bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) dberr = (irq == edac->db_irq) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) sm_offset = dberr ? A10_SYSMGR_ECC_INTSTAT_DERR_OFST :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) A10_SYSMGR_ECC_INTSTAT_SERR_OFST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) chained_irq_enter(chip, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) regmap_read(edac->ecc_mgr_map, sm_offset, &irq_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) bits = irq_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) for_each_set_bit(bit, &bits, 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) irq = irq_linear_revmap(edac->domain, dberr * 32 + bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) if (irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) generic_handle_irq(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) chained_irq_exit(chip, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) static int validate_parent_available(struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) struct device_node *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) /* SDRAM must be present for Linux (implied parent) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) if (of_device_is_compatible(np, "altr,sdram-edac-s10"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) /* Ensure parent device is enabled if parent node exists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) parent = of_parse_phandle(np, "altr,ecc-parent", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) if (parent && !of_device_is_available(parent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) of_node_put(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) static int get_s10_sdram_edac_resource(struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) struct resource *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) struct device_node *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) parent = of_parse_phandle(np, "altr,sdr-syscon", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) if (!parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) ret = of_address_to_resource(parent, 0, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) of_node_put(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) static int altr_edac_a10_device_add(struct altr_arria10_edac *edac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) struct edac_device_ctl_info *dci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) struct altr_edac_device_dev *altdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) char *ecc_name = (char *)np->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) struct resource res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) int edac_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) const struct edac_device_prv_data *prv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) /* Get matching node and check for valid result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) const struct of_device_id *pdev_id =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) of_match_node(altr_edac_a10_device_of_match, np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) if (IS_ERR_OR_NULL(pdev_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) /* Get driver specific data for this EDAC device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) prv = pdev_id->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) if (IS_ERR_OR_NULL(prv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) if (validate_parent_available(np))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) if (!devres_open_group(edac->dev, altr_edac_a10_device_add, GFP_KERNEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) if (of_device_is_compatible(np, "altr,sdram-edac-s10"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) rc = get_s10_sdram_edac_resource(np, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) rc = of_address_to_resource(np, 0, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) edac_printk(KERN_ERR, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) "%s: no resource address\n", ecc_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) goto err_release_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) edac_idx = edac_device_alloc_index();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) dci = edac_device_alloc_ctl_info(sizeof(*altdev), ecc_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 1, ecc_name, 1, 0, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) edac_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) if (!dci) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) edac_printk(KERN_ERR, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) "%s: Unable to allocate EDAC device\n", ecc_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) goto err_release_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) altdev = dci->pvt_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) dci->dev = edac->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) altdev->edac_dev_name = ecc_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) altdev->edac_idx = edac_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) altdev->edac = edac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) altdev->edac_dev = dci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) altdev->data = prv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) altdev->ddev = *edac->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) dci->dev = &altdev->ddev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) dci->ctl_name = "Altera ECC Manager";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) dci->mod_name = ecc_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) dci->dev_name = ecc_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) altdev->base = devm_ioremap_resource(edac->dev, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) if (IS_ERR(altdev->base)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) rc = PTR_ERR(altdev->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) goto err_release_group1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) /* Check specific dependencies for the module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) if (altdev->data->setup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) rc = altdev->data->setup(altdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) goto err_release_group1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) altdev->sb_irq = irq_of_parse_and_map(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) if (!altdev->sb_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) edac_printk(KERN_ERR, EDAC_DEVICE, "Error allocating SBIRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) goto err_release_group1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) rc = devm_request_irq(edac->dev, altdev->sb_irq, prv->ecc_irq_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) ecc_name, altdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) edac_printk(KERN_ERR, EDAC_DEVICE, "No SBERR IRQ resource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) goto err_release_group1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) #ifdef CONFIG_ARCH_STRATIX10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) /* Use IRQ to determine SError origin instead of assigning IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) rc = of_property_read_u32_index(np, "interrupts", 0, &altdev->db_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) edac_printk(KERN_ERR, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) "Unable to parse DB IRQ index\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) goto err_release_group1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) altdev->db_irq = irq_of_parse_and_map(np, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) if (!altdev->db_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) edac_printk(KERN_ERR, EDAC_DEVICE, "Error allocating DBIRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) goto err_release_group1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) rc = devm_request_irq(edac->dev, altdev->db_irq, prv->ecc_irq_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) ecc_name, altdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) edac_printk(KERN_ERR, EDAC_DEVICE, "No DBERR IRQ resource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) goto err_release_group1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) rc = edac_device_add_device(dci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) dev_err(edac->dev, "edac_device_add_device failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) goto err_release_group1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) altr_create_edacdev_dbgfs(dci, prv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) list_add(&altdev->next, &edac->a10_ecc_devices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) devres_remove_group(edac->dev, altr_edac_a10_device_add);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) err_release_group1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) edac_device_free_ctl_info(dci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) err_release_group:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) devres_release_group(edac->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) edac_printk(KERN_ERR, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) "%s:Error setting up EDAC device: %d\n", ecc_name, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) static void a10_eccmgr_irq_mask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) struct altr_arria10_edac *edac = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) regmap_write(edac->ecc_mgr_map, A10_SYSMGR_ECC_INTMASK_SET_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) BIT(d->hwirq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) static void a10_eccmgr_irq_unmask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) struct altr_arria10_edac *edac = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) regmap_write(edac->ecc_mgr_map, A10_SYSMGR_ECC_INTMASK_CLR_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) BIT(d->hwirq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) static int a10_eccmgr_irqdomain_map(struct irq_domain *d, unsigned int irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) irq_hw_number_t hwirq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) struct altr_arria10_edac *edac = d->host_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) irq_set_chip_and_handler(irq, &edac->irq_chip, handle_simple_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) irq_set_chip_data(irq, edac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) irq_set_noprobe(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) static const struct irq_domain_ops a10_eccmgr_ic_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) .map = a10_eccmgr_irqdomain_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) .xlate = irq_domain_xlate_twocell,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) /************** Stratix 10 EDAC Double Bit Error Handler ************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) #define to_a10edac(p, m) container_of(p, struct altr_arria10_edac, m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) #ifdef CONFIG_ARCH_STRATIX10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) /* panic routine issues reboot on non-zero panic_timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) extern int panic_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) * The double bit error is handled through SError which is fatal. This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) * called as a panic notifier to printout ECC error info as part of the panic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) static int s10_edac_dberr_handler(struct notifier_block *this,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) unsigned long event, void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) struct altr_arria10_edac *edac = to_a10edac(this, panic_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) int err_addr, dberror;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) regmap_read(edac->ecc_mgr_map, S10_SYSMGR_ECC_INTSTAT_DERR_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) &dberror);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) regmap_write(edac->ecc_mgr_map, S10_SYSMGR_UE_VAL_OFST, dberror);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) if (dberror & S10_DBE_IRQ_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) struct list_head *position;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) struct altr_edac_device_dev *ed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) struct arm_smccc_res result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) /* Find the matching DBE in the list of devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) list_for_each(position, &edac->a10_ecc_devices) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) ed = list_entry(position, struct altr_edac_device_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) if (!(BIT(ed->db_irq) & dberror))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) writel(ALTR_A10_ECC_DERRPENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) ed->base + ALTR_A10_ECC_INTSTAT_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) err_addr = readl(ed->base + ALTR_S10_DERR_ADDRA_OFST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) regmap_write(edac->ecc_mgr_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) S10_SYSMGR_UE_ADDR_OFST, err_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) edac_printk(KERN_ERR, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) "EDAC: [Fatal DBE on %s @ 0x%08X]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) ed->edac_dev_name, err_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) /* Notify the System through SMC. Reboot delay = 1 second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) panic_timeout = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) arm_smccc_smc(INTEL_SIP_SMC_ECC_DBE, dberror, 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 0, 0, &result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) /****************** Arria 10 EDAC Probe Function *********************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) static int altr_edac_a10_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) struct altr_arria10_edac *edac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) struct device_node *child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) edac = devm_kzalloc(&pdev->dev, sizeof(*edac), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) if (!edac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) edac->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) platform_set_drvdata(pdev, edac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) INIT_LIST_HEAD(&edac->a10_ecc_devices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) edac->ecc_mgr_map =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) altr_sysmgr_regmap_lookup_by_phandle(pdev->dev.of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) "altr,sysmgr-syscon");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) if (IS_ERR(edac->ecc_mgr_map)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) edac_printk(KERN_ERR, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) "Unable to get syscon altr,sysmgr-syscon\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) return PTR_ERR(edac->ecc_mgr_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) edac->irq_chip.name = pdev->dev.of_node->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) edac->irq_chip.irq_mask = a10_eccmgr_irq_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) edac->irq_chip.irq_unmask = a10_eccmgr_irq_unmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) edac->domain = irq_domain_add_linear(pdev->dev.of_node, 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) &a10_eccmgr_ic_ops, edac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) if (!edac->domain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) dev_err(&pdev->dev, "Error adding IRQ domain\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) edac->sb_irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) if (edac->sb_irq < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) dev_err(&pdev->dev, "No SBERR IRQ resource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) return edac->sb_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) irq_set_chained_handler_and_data(edac->sb_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) altr_edac_a10_irq_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) edac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) #ifdef CONFIG_ARCH_STRATIX10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) int dberror, err_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) edac->panic_notifier.notifier_call = s10_edac_dberr_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) atomic_notifier_chain_register(&panic_notifier_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) &edac->panic_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) /* Printout a message if uncorrectable error previously. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) regmap_read(edac->ecc_mgr_map, S10_SYSMGR_UE_VAL_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) &dberror);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) if (dberror) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) regmap_read(edac->ecc_mgr_map, S10_SYSMGR_UE_ADDR_OFST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) &err_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) edac_printk(KERN_ERR, EDAC_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) "Previous Boot UE detected[0x%X] @ 0x%X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) dberror, err_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) /* Reset the sticky registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) regmap_write(edac->ecc_mgr_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) S10_SYSMGR_UE_VAL_OFST, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) regmap_write(edac->ecc_mgr_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) S10_SYSMGR_UE_ADDR_OFST, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) edac->db_irq = platform_get_irq(pdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) if (edac->db_irq < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) dev_err(&pdev->dev, "No DBERR IRQ resource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) return edac->db_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) irq_set_chained_handler_and_data(edac->db_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) altr_edac_a10_irq_handler, edac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) for_each_child_of_node(pdev->dev.of_node, child) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) if (!of_device_is_available(child))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) if (of_match_node(altr_edac_a10_device_of_match, child))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) altr_edac_a10_device_add(edac, child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) #ifdef CONFIG_EDAC_ALTERA_SDRAM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) else if (of_device_is_compatible(child, "altr,sdram-edac-a10"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) of_platform_populate(pdev->dev.of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) altr_sdram_ctrl_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) NULL, &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) static const struct of_device_id altr_edac_a10_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) { .compatible = "altr,socfpga-a10-ecc-manager" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) { .compatible = "altr,socfpga-s10-ecc-manager" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) MODULE_DEVICE_TABLE(of, altr_edac_a10_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) static struct platform_driver altr_edac_a10_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) .probe = altr_edac_a10_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) .name = "socfpga_a10_ecc_manager",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) .of_match_table = altr_edac_a10_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) module_platform_driver(altr_edac_a10_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) MODULE_AUTHOR("Thor Thayer");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) MODULE_DESCRIPTION("EDAC Driver for Altera Memories");