blob: 6f5d586fa0a08c23288ebf02cad22a07bc889c2d [file] [log] [blame]
Thor Thayer71bcada2014-09-03 10:27:54 -05001/*
Thor Thayerc3eea192016-02-10 13:26:21 -06002 * Copyright Altera Corporation (C) 2014-2016. All rights reserved.
Thor Thayer71bcada2014-09-03 10:27:54 -05003 * Copyright 2011-2012 Calxeda, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Adapted from the highbank_mc_edac driver.
18 */
19
Thor Thayerc3eea192016-02-10 13:26:21 -060020#include <asm/cacheflush.h>
Thor Thayer71bcada2014-09-03 10:27:54 -050021#include <linux/ctype.h>
22#include <linux/edac.h>
Thor Thayerc3eea192016-02-10 13:26:21 -060023#include <linux/genalloc.h>
Thor Thayer71bcada2014-09-03 10:27:54 -050024#include <linux/interrupt.h>
Thor Thayer13ab8442016-06-07 15:35:57 -050025#include <linux/irqchip/chained_irq.h>
Thor Thayer71bcada2014-09-03 10:27:54 -050026#include <linux/kernel.h>
27#include <linux/mfd/syscon.h>
Thor Thayer588cb032016-03-21 11:01:44 -050028#include <linux/of_address.h>
Thor Thayer13ab8442016-06-07 15:35:57 -050029#include <linux/of_irq.h>
Thor Thayer71bcada2014-09-03 10:27:54 -050030#include <linux/of_platform.h>
31#include <linux/platform_device.h>
32#include <linux/regmap.h>
33#include <linux/types.h>
34#include <linux/uaccess.h>
35
Thor Thayer143f4a52015-06-04 09:28:46 -050036#include "altera_edac.h"
Thor Thayer71bcada2014-09-03 10:27:54 -050037#include "edac_core.h"
38#include "edac_module.h"
39
40#define EDAC_MOD_STR "altera_edac"
41#define EDAC_VERSION "1"
Thor Thayerc3eea192016-02-10 13:26:21 -060042#define EDAC_DEVICE "Altera"
Thor Thayer71bcada2014-09-03 10:27:54 -050043
Thor Thayer143f4a52015-06-04 09:28:46 -050044static const struct altr_sdram_prv_data c5_data = {
45 .ecc_ctrl_offset = CV_CTLCFG_OFST,
46 .ecc_ctl_en_mask = CV_CTLCFG_ECC_AUTO_EN,
47 .ecc_stat_offset = CV_DRAMSTS_OFST,
48 .ecc_stat_ce_mask = CV_DRAMSTS_SBEERR,
49 .ecc_stat_ue_mask = CV_DRAMSTS_DBEERR,
50 .ecc_saddr_offset = CV_ERRADDR_OFST,
Thor Thayer73bcc942015-06-04 09:28:47 -050051 .ecc_daddr_offset = CV_ERRADDR_OFST,
Thor Thayer143f4a52015-06-04 09:28:46 -050052 .ecc_cecnt_offset = CV_SBECOUNT_OFST,
53 .ecc_uecnt_offset = CV_DBECOUNT_OFST,
54 .ecc_irq_en_offset = CV_DRAMINTR_OFST,
55 .ecc_irq_en_mask = CV_DRAMINTR_INTREN,
56 .ecc_irq_clr_offset = CV_DRAMINTR_OFST,
57 .ecc_irq_clr_mask = (CV_DRAMINTR_INTRCLR | CV_DRAMINTR_INTREN),
58 .ecc_cnt_rst_offset = CV_DRAMINTR_OFST,
59 .ecc_cnt_rst_mask = CV_DRAMINTR_INTRCLR,
Thor Thayer143f4a52015-06-04 09:28:46 -050060 .ce_ue_trgr_offset = CV_CTLCFG_OFST,
61 .ce_set_mask = CV_CTLCFG_GEN_SB_ERR,
62 .ue_set_mask = CV_CTLCFG_GEN_DB_ERR,
Thor Thayer71bcada2014-09-03 10:27:54 -050063};
64
Thor Thayer73bcc942015-06-04 09:28:47 -050065static const struct altr_sdram_prv_data a10_data = {
66 .ecc_ctrl_offset = A10_ECCCTRL1_OFST,
67 .ecc_ctl_en_mask = A10_ECCCTRL1_ECC_EN,
68 .ecc_stat_offset = A10_INTSTAT_OFST,
69 .ecc_stat_ce_mask = A10_INTSTAT_SBEERR,
70 .ecc_stat_ue_mask = A10_INTSTAT_DBEERR,
71 .ecc_saddr_offset = A10_SERRADDR_OFST,
72 .ecc_daddr_offset = A10_DERRADDR_OFST,
73 .ecc_irq_en_offset = A10_ERRINTEN_OFST,
74 .ecc_irq_en_mask = A10_ECC_IRQ_EN_MASK,
75 .ecc_irq_clr_offset = A10_INTSTAT_OFST,
76 .ecc_irq_clr_mask = (A10_INTSTAT_SBEERR | A10_INTSTAT_DBEERR),
77 .ecc_cnt_rst_offset = A10_ECCCTRL1_OFST,
78 .ecc_cnt_rst_mask = A10_ECC_CNT_RESET_MASK,
Thor Thayer73bcc942015-06-04 09:28:47 -050079 .ce_ue_trgr_offset = A10_DIAGINTTEST_OFST,
80 .ce_set_mask = A10_DIAGINT_TSERRA_MASK,
81 .ue_set_mask = A10_DIAGINT_TDERRA_MASK,
Thor Thayer73bcc942015-06-04 09:28:47 -050082};
83
Thor Thayerc3eea192016-02-10 13:26:21 -060084/*********************** EDAC Memory Controller Functions ****************/
85
86/* The SDRAM controller uses the EDAC Memory Controller framework. */
87
Thor Thayer71bcada2014-09-03 10:27:54 -050088static irqreturn_t altr_sdram_mc_err_handler(int irq, void *dev_id)
89{
90 struct mem_ctl_info *mci = dev_id;
91 struct altr_sdram_mc_data *drvdata = mci->pvt_info;
Thor Thayer143f4a52015-06-04 09:28:46 -050092 const struct altr_sdram_prv_data *priv = drvdata->data;
Thor Thayer73bcc942015-06-04 09:28:47 -050093 u32 status, err_count = 1, err_addr;
Thor Thayer71bcada2014-09-03 10:27:54 -050094
Thor Thayer143f4a52015-06-04 09:28:46 -050095 regmap_read(drvdata->mc_vbase, priv->ecc_stat_offset, &status);
Thor Thayer71bcada2014-09-03 10:27:54 -050096
Thor Thayer143f4a52015-06-04 09:28:46 -050097 if (status & priv->ecc_stat_ue_mask) {
Thor Thayer73bcc942015-06-04 09:28:47 -050098 regmap_read(drvdata->mc_vbase, priv->ecc_daddr_offset,
99 &err_addr);
100 if (priv->ecc_uecnt_offset)
101 regmap_read(drvdata->mc_vbase, priv->ecc_uecnt_offset,
102 &err_count);
Thor Thayer71bcada2014-09-03 10:27:54 -0500103 panic("\nEDAC: [%d Uncorrectable errors @ 0x%08X]\n",
104 err_count, err_addr);
105 }
Thor Thayer143f4a52015-06-04 09:28:46 -0500106 if (status & priv->ecc_stat_ce_mask) {
Thor Thayer73bcc942015-06-04 09:28:47 -0500107 regmap_read(drvdata->mc_vbase, priv->ecc_saddr_offset,
108 &err_addr);
109 if (priv->ecc_uecnt_offset)
110 regmap_read(drvdata->mc_vbase, priv->ecc_cecnt_offset,
111 &err_count);
Thor Thayer71bcada2014-09-03 10:27:54 -0500112 edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, err_count,
113 err_addr >> PAGE_SHIFT,
114 err_addr & ~PAGE_MASK, 0,
115 0, 0, -1, mci->ctl_name, "");
Thor Thayer73bcc942015-06-04 09:28:47 -0500116 /* Clear IRQ to resume */
117 regmap_write(drvdata->mc_vbase, priv->ecc_irq_clr_offset,
118 priv->ecc_irq_clr_mask);
119
120 return IRQ_HANDLED;
Thor Thayer71bcada2014-09-03 10:27:54 -0500121 }
Thor Thayer73bcc942015-06-04 09:28:47 -0500122 return IRQ_NONE;
Thor Thayer71bcada2014-09-03 10:27:54 -0500123}
124
Thor Thayer71bcada2014-09-03 10:27:54 -0500125static ssize_t altr_sdr_mc_err_inject_write(struct file *file,
126 const char __user *data,
127 size_t count, loff_t *ppos)
128{
129 struct mem_ctl_info *mci = file->private_data;
130 struct altr_sdram_mc_data *drvdata = mci->pvt_info;
Thor Thayer143f4a52015-06-04 09:28:46 -0500131 const struct altr_sdram_prv_data *priv = drvdata->data;
Thor Thayer71bcada2014-09-03 10:27:54 -0500132 u32 *ptemp;
133 dma_addr_t dma_handle;
134 u32 reg, read_reg;
135
136 ptemp = dma_alloc_coherent(mci->pdev, 16, &dma_handle, GFP_KERNEL);
137 if (!ptemp) {
138 dma_free_coherent(mci->pdev, 16, ptemp, dma_handle);
139 edac_printk(KERN_ERR, EDAC_MC,
140 "Inject: Buffer Allocation error\n");
141 return -ENOMEM;
142 }
143
Thor Thayer143f4a52015-06-04 09:28:46 -0500144 regmap_read(drvdata->mc_vbase, priv->ce_ue_trgr_offset,
145 &read_reg);
146 read_reg &= ~(priv->ce_set_mask | priv->ue_set_mask);
Thor Thayer71bcada2014-09-03 10:27:54 -0500147
148 /* Error are injected by writing a word while the SBE or DBE
149 * bit in the CTLCFG register is set. Reading the word will
150 * trigger the SBE or DBE error and the corresponding IRQ.
151 */
152 if (count == 3) {
153 edac_printk(KERN_ALERT, EDAC_MC,
154 "Inject Double bit error\n");
Thor Thayer143f4a52015-06-04 09:28:46 -0500155 regmap_write(drvdata->mc_vbase, priv->ce_ue_trgr_offset,
156 (read_reg | priv->ue_set_mask));
Thor Thayer71bcada2014-09-03 10:27:54 -0500157 } else {
158 edac_printk(KERN_ALERT, EDAC_MC,
159 "Inject Single bit error\n");
Thor Thayer143f4a52015-06-04 09:28:46 -0500160 regmap_write(drvdata->mc_vbase, priv->ce_ue_trgr_offset,
161 (read_reg | priv->ce_set_mask));
Thor Thayer71bcada2014-09-03 10:27:54 -0500162 }
163
164 ptemp[0] = 0x5A5A5A5A;
165 ptemp[1] = 0xA5A5A5A5;
166
167 /* Clear the error injection bits */
Thor Thayer143f4a52015-06-04 09:28:46 -0500168 regmap_write(drvdata->mc_vbase, priv->ce_ue_trgr_offset, read_reg);
Thor Thayer71bcada2014-09-03 10:27:54 -0500169 /* Ensure it has been written out */
170 wmb();
171
172 /*
173 * To trigger the error, we need to read the data back
174 * (the data was written with errors above).
175 * The ACCESS_ONCE macros and printk are used to prevent the
176 * the compiler optimizing these reads out.
177 */
178 reg = ACCESS_ONCE(ptemp[0]);
179 read_reg = ACCESS_ONCE(ptemp[1]);
180 /* Force Read */
181 rmb();
182
183 edac_printk(KERN_ALERT, EDAC_MC, "Read Data [0x%X, 0x%X]\n",
184 reg, read_reg);
185
186 dma_free_coherent(mci->pdev, 16, ptemp, dma_handle);
187
188 return count;
189}
190
191static const struct file_operations altr_sdr_mc_debug_inject_fops = {
192 .open = simple_open,
193 .write = altr_sdr_mc_err_inject_write,
194 .llseek = generic_file_llseek,
195};
196
197static void altr_sdr_mc_create_debugfs_nodes(struct mem_ctl_info *mci)
198{
Borislav Petkovbba3b312015-09-22 12:27:29 +0200199 if (!IS_ENABLED(CONFIG_EDAC_DEBUG))
200 return;
201
202 if (!mci->debugfs)
203 return;
204
205 edac_debugfs_create_file("inject_ctrl", S_IWUSR, mci->debugfs, mci,
206 &altr_sdr_mc_debug_inject_fops);
Thor Thayer71bcada2014-09-03 10:27:54 -0500207}
Thor Thayer71bcada2014-09-03 10:27:54 -0500208
Thor Thayerf9ae4872015-06-04 09:28:45 -0500209/* Get total memory size from Open Firmware DTB */
210static unsigned long get_total_mem(void)
Thor Thayer71bcada2014-09-03 10:27:54 -0500211{
Thor Thayerf9ae4872015-06-04 09:28:45 -0500212 struct device_node *np = NULL;
213 const unsigned int *reg, *reg_end;
214 int len, sw, aw;
215 unsigned long start, size, total_mem = 0;
Thor Thayer71bcada2014-09-03 10:27:54 -0500216
Thor Thayerf9ae4872015-06-04 09:28:45 -0500217 for_each_node_by_type(np, "memory") {
218 aw = of_n_addr_cells(np);
219 sw = of_n_size_cells(np);
220 reg = (const unsigned int *)of_get_property(np, "reg", &len);
221 reg_end = reg + (len / sizeof(u32));
Thor Thayer71bcada2014-09-03 10:27:54 -0500222
Thor Thayerf9ae4872015-06-04 09:28:45 -0500223 total_mem = 0;
224 do {
225 start = of_read_number(reg, aw);
226 reg += aw;
227 size = of_read_number(reg, sw);
228 reg += sw;
229 total_mem += size;
230 } while (reg < reg_end);
231 }
232 edac_dbg(0, "total_mem 0x%lx\n", total_mem);
233 return total_mem;
Thor Thayer71bcada2014-09-03 10:27:54 -0500234}
235
Thor Thayer143f4a52015-06-04 09:28:46 -0500236static const struct of_device_id altr_sdram_ctrl_of_match[] = {
Arnd Bergmann2c911f62016-04-16 22:13:55 +0200237 { .compatible = "altr,sdram-edac", .data = &c5_data},
238 { .compatible = "altr,sdram-edac-a10", .data = &a10_data},
Thor Thayer143f4a52015-06-04 09:28:46 -0500239 {},
240};
241MODULE_DEVICE_TABLE(of, altr_sdram_ctrl_of_match);
242
Thor Thayer73bcc942015-06-04 09:28:47 -0500243static int a10_init(struct regmap *mc_vbase)
244{
245 if (regmap_update_bits(mc_vbase, A10_INTMODE_OFST,
246 A10_INTMODE_SB_INT, A10_INTMODE_SB_INT)) {
247 edac_printk(KERN_ERR, EDAC_MC,
248 "Error setting SB IRQ mode\n");
249 return -ENODEV;
250 }
251
252 if (regmap_write(mc_vbase, A10_SERRCNTREG_OFST, 1)) {
253 edac_printk(KERN_ERR, EDAC_MC,
254 "Error setting trigger count\n");
255 return -ENODEV;
256 }
257
258 return 0;
259}
260
261static int a10_unmask_irq(struct platform_device *pdev, u32 mask)
262{
263 void __iomem *sm_base;
264 int ret = 0;
265
266 if (!request_mem_region(A10_SYMAN_INTMASK_CLR, sizeof(u32),
267 dev_name(&pdev->dev))) {
268 edac_printk(KERN_ERR, EDAC_MC,
269 "Unable to request mem region\n");
270 return -EBUSY;
271 }
272
273 sm_base = ioremap(A10_SYMAN_INTMASK_CLR, sizeof(u32));
274 if (!sm_base) {
275 edac_printk(KERN_ERR, EDAC_MC,
276 "Unable to ioremap device\n");
277
278 ret = -ENOMEM;
279 goto release;
280 }
281
282 iowrite32(mask, sm_base);
283
284 iounmap(sm_base);
285
286release:
287 release_mem_region(A10_SYMAN_INTMASK_CLR, sizeof(u32));
288
289 return ret;
290}
291
Thor Thayer71bcada2014-09-03 10:27:54 -0500292static int altr_sdram_probe(struct platform_device *pdev)
293{
Thor Thayer143f4a52015-06-04 09:28:46 -0500294 const struct of_device_id *id;
Thor Thayer71bcada2014-09-03 10:27:54 -0500295 struct edac_mc_layer layers[2];
296 struct mem_ctl_info *mci;
297 struct altr_sdram_mc_data *drvdata;
Thor Thayer143f4a52015-06-04 09:28:46 -0500298 const struct altr_sdram_prv_data *priv;
Thor Thayer71bcada2014-09-03 10:27:54 -0500299 struct regmap *mc_vbase;
300 struct dimm_info *dimm;
Thor Thayer143f4a52015-06-04 09:28:46 -0500301 u32 read_reg;
Thor Thayer73bcc942015-06-04 09:28:47 -0500302 int irq, irq2, res = 0;
303 unsigned long mem_size, irqflags = 0;
Thor Thayer71bcada2014-09-03 10:27:54 -0500304
Thor Thayer143f4a52015-06-04 09:28:46 -0500305 id = of_match_device(altr_sdram_ctrl_of_match, &pdev->dev);
306 if (!id)
307 return -ENODEV;
308
Thor Thayer71bcada2014-09-03 10:27:54 -0500309 /* Grab the register range from the sdr controller in device tree */
310 mc_vbase = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
311 "altr,sdr-syscon");
312 if (IS_ERR(mc_vbase)) {
313 edac_printk(KERN_ERR, EDAC_MC,
314 "regmap for altr,sdr-syscon lookup failed.\n");
315 return -ENODEV;
316 }
317
Thor Thayer143f4a52015-06-04 09:28:46 -0500318 /* Check specific dependencies for the module */
319 priv = of_match_node(altr_sdram_ctrl_of_match,
320 pdev->dev.of_node)->data;
321
322 /* Validate the SDRAM controller has ECC enabled */
323 if (regmap_read(mc_vbase, priv->ecc_ctrl_offset, &read_reg) ||
324 ((read_reg & priv->ecc_ctl_en_mask) != priv->ecc_ctl_en_mask)) {
Thor Thayer71bcada2014-09-03 10:27:54 -0500325 edac_printk(KERN_ERR, EDAC_MC,
326 "No ECC/ECC disabled [0x%08X]\n", read_reg);
327 return -ENODEV;
328 }
329
330 /* Grab memory size from device tree. */
Thor Thayerf9ae4872015-06-04 09:28:45 -0500331 mem_size = get_total_mem();
Thor Thayer71bcada2014-09-03 10:27:54 -0500332 if (!mem_size) {
Thor Thayerf9ae4872015-06-04 09:28:45 -0500333 edac_printk(KERN_ERR, EDAC_MC, "Unable to calculate memory size\n");
Thor Thayer71bcada2014-09-03 10:27:54 -0500334 return -ENODEV;
335 }
336
Thor Thayer143f4a52015-06-04 09:28:46 -0500337 /* Ensure the SDRAM Interrupt is disabled */
338 if (regmap_update_bits(mc_vbase, priv->ecc_irq_en_offset,
339 priv->ecc_irq_en_mask, 0)) {
Thor Thayer71bcada2014-09-03 10:27:54 -0500340 edac_printk(KERN_ERR, EDAC_MC,
Thor Thayer143f4a52015-06-04 09:28:46 -0500341 "Error disabling SDRAM ECC IRQ\n");
342 return -ENODEV;
343 }
344
345 /* Toggle to clear the SDRAM Error count */
346 if (regmap_update_bits(mc_vbase, priv->ecc_cnt_rst_offset,
347 priv->ecc_cnt_rst_mask,
348 priv->ecc_cnt_rst_mask)) {
349 edac_printk(KERN_ERR, EDAC_MC,
350 "Error clearing SDRAM ECC count\n");
351 return -ENODEV;
352 }
353
354 if (regmap_update_bits(mc_vbase, priv->ecc_cnt_rst_offset,
355 priv->ecc_cnt_rst_mask, 0)) {
356 edac_printk(KERN_ERR, EDAC_MC,
357 "Error clearing SDRAM ECC count\n");
Thor Thayer71bcada2014-09-03 10:27:54 -0500358 return -ENODEV;
359 }
360
361 irq = platform_get_irq(pdev, 0);
362 if (irq < 0) {
363 edac_printk(KERN_ERR, EDAC_MC,
364 "No irq %d in DT\n", irq);
365 return -ENODEV;
366 }
367
Thor Thayer73bcc942015-06-04 09:28:47 -0500368 /* Arria10 has a 2nd IRQ */
369 irq2 = platform_get_irq(pdev, 1);
370
Thor Thayer71bcada2014-09-03 10:27:54 -0500371 layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
372 layers[0].size = 1;
373 layers[0].is_virt_csrow = true;
374 layers[1].type = EDAC_MC_LAYER_CHANNEL;
375 layers[1].size = 1;
376 layers[1].is_virt_csrow = false;
377 mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers,
378 sizeof(struct altr_sdram_mc_data));
379 if (!mci)
380 return -ENOMEM;
381
382 mci->pdev = &pdev->dev;
383 drvdata = mci->pvt_info;
384 drvdata->mc_vbase = mc_vbase;
Thor Thayer143f4a52015-06-04 09:28:46 -0500385 drvdata->data = priv;
Thor Thayer71bcada2014-09-03 10:27:54 -0500386 platform_set_drvdata(pdev, mci);
387
388 if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL)) {
Thor Thayer143f4a52015-06-04 09:28:46 -0500389 edac_printk(KERN_ERR, EDAC_MC,
390 "Unable to get managed device resource\n");
Thor Thayer71bcada2014-09-03 10:27:54 -0500391 res = -ENOMEM;
392 goto free;
393 }
394
395 mci->mtype_cap = MEM_FLAG_DDR3;
396 mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
397 mci->edac_cap = EDAC_FLAG_SECDED;
398 mci->mod_name = EDAC_MOD_STR;
399 mci->mod_ver = EDAC_VERSION;
400 mci->ctl_name = dev_name(&pdev->dev);
401 mci->scrub_mode = SCRUB_SW_SRC;
402 mci->dev_name = dev_name(&pdev->dev);
403
404 dimm = *mci->dimms;
405 dimm->nr_pages = ((mem_size - 1) >> PAGE_SHIFT) + 1;
406 dimm->grain = 8;
407 dimm->dtype = DEV_X8;
408 dimm->mtype = MEM_DDR3;
409 dimm->edac_mode = EDAC_SECDED;
410
411 res = edac_mc_add_mc(mci);
412 if (res < 0)
413 goto err;
414
Thor Thayer73bcc942015-06-04 09:28:47 -0500415 /* Only the Arria10 has separate IRQs */
416 if (irq2 > 0) {
417 /* Arria10 specific initialization */
418 res = a10_init(mc_vbase);
419 if (res < 0)
420 goto err2;
421
422 res = devm_request_irq(&pdev->dev, irq2,
423 altr_sdram_mc_err_handler,
424 IRQF_SHARED, dev_name(&pdev->dev), mci);
425 if (res < 0) {
426 edac_mc_printk(mci, KERN_ERR,
427 "Unable to request irq %d\n", irq2);
428 res = -ENODEV;
429 goto err2;
430 }
431
432 res = a10_unmask_irq(pdev, A10_DDR0_IRQ_MASK);
433 if (res < 0)
434 goto err2;
435
436 irqflags = IRQF_SHARED;
437 }
438
Thor Thayer71bcada2014-09-03 10:27:54 -0500439 res = devm_request_irq(&pdev->dev, irq, altr_sdram_mc_err_handler,
Thor Thayer73bcc942015-06-04 09:28:47 -0500440 irqflags, dev_name(&pdev->dev), mci);
Thor Thayer71bcada2014-09-03 10:27:54 -0500441 if (res < 0) {
442 edac_mc_printk(mci, KERN_ERR,
443 "Unable to request irq %d\n", irq);
444 res = -ENODEV;
445 goto err2;
446 }
447
Thor Thayer143f4a52015-06-04 09:28:46 -0500448 /* Infrastructure ready - enable the IRQ */
449 if (regmap_update_bits(drvdata->mc_vbase, priv->ecc_irq_en_offset,
450 priv->ecc_irq_en_mask, priv->ecc_irq_en_mask)) {
Thor Thayer71bcada2014-09-03 10:27:54 -0500451 edac_mc_printk(mci, KERN_ERR,
452 "Error enabling SDRAM ECC IRQ\n");
453 res = -ENODEV;
454 goto err2;
455 }
456
457 altr_sdr_mc_create_debugfs_nodes(mci);
458
459 devres_close_group(&pdev->dev, NULL);
460
461 return 0;
462
463err2:
464 edac_mc_del_mc(&pdev->dev);
465err:
466 devres_release_group(&pdev->dev, NULL);
467free:
468 edac_mc_free(mci);
469 edac_printk(KERN_ERR, EDAC_MC,
470 "EDAC Probe Failed; Error %d\n", res);
471
472 return res;
473}
474
475static int altr_sdram_remove(struct platform_device *pdev)
476{
477 struct mem_ctl_info *mci = platform_get_drvdata(pdev);
478
479 edac_mc_del_mc(&pdev->dev);
480 edac_mc_free(mci);
481 platform_set_drvdata(pdev, NULL);
482
483 return 0;
484}
485
Alan Tull6f2b6422015-06-05 08:49:15 -0500486/*
487 * If you want to suspend, need to disable EDAC by removing it
488 * from the device tree or defconfig.
489 */
490#ifdef CONFIG_PM
491static int altr_sdram_prepare(struct device *dev)
492{
493 pr_err("Suspend not allowed when EDAC is enabled.\n");
494
495 return -EPERM;
496}
497
498static const struct dev_pm_ops altr_sdram_pm_ops = {
499 .prepare = altr_sdram_prepare,
500};
501#endif
502
Thor Thayer71bcada2014-09-03 10:27:54 -0500503static struct platform_driver altr_sdram_edac_driver = {
504 .probe = altr_sdram_probe,
505 .remove = altr_sdram_remove,
506 .driver = {
507 .name = "altr_sdram_edac",
Alan Tull6f2b6422015-06-05 08:49:15 -0500508#ifdef CONFIG_PM
509 .pm = &altr_sdram_pm_ops,
510#endif
Thor Thayer71bcada2014-09-03 10:27:54 -0500511 .of_match_table = altr_sdram_ctrl_of_match,
512 },
513};
514
515module_platform_driver(altr_sdram_edac_driver);
516
Thor Thayerc3eea192016-02-10 13:26:21 -0600517/************************* EDAC Parent Probe *************************/
518
519static const struct of_device_id altr_edac_device_of_match[];
520
521static const struct of_device_id altr_edac_of_match[] = {
522 { .compatible = "altr,socfpga-ecc-manager" },
523 {},
524};
525MODULE_DEVICE_TABLE(of, altr_edac_of_match);
526
527static int altr_edac_probe(struct platform_device *pdev)
528{
529 of_platform_populate(pdev->dev.of_node, altr_edac_device_of_match,
530 NULL, &pdev->dev);
531 return 0;
532}
533
534static struct platform_driver altr_edac_driver = {
535 .probe = altr_edac_probe,
536 .driver = {
537 .name = "socfpga_ecc_manager",
538 .of_match_table = altr_edac_of_match,
539 },
540};
541module_platform_driver(altr_edac_driver);
542
543/************************* EDAC Device Functions *************************/
544
545/*
546 * EDAC Device Functions (shared between various IPs).
547 * The discrete memories use the EDAC Device framework. The probe
548 * and error handling functions are very similar between memories
549 * so they are shared. The memory allocation and freeing for EDAC
550 * trigger testing are different for each memory.
551 */
552
553const struct edac_device_prv_data ocramecc_data;
554const struct edac_device_prv_data l2ecc_data;
Thor Thayerc7b4be82016-04-06 20:22:54 -0500555const struct edac_device_prv_data a10_ocramecc_data;
Thor Thayer588cb032016-03-21 11:01:44 -0500556const struct edac_device_prv_data a10_l2ecc_data;
Thor Thayerc3eea192016-02-10 13:26:21 -0600557
Thor Thayerc3eea192016-02-10 13:26:21 -0600558static irqreturn_t altr_edac_device_handler(int irq, void *dev_id)
559{
560 irqreturn_t ret_value = IRQ_NONE;
561 struct edac_device_ctl_info *dci = dev_id;
562 struct altr_edac_device_dev *drvdata = dci->pvt_info;
563 const struct edac_device_prv_data *priv = drvdata->data;
564
565 if (irq == drvdata->sb_irq) {
566 if (priv->ce_clear_mask)
567 writel(priv->ce_clear_mask, drvdata->base);
568 edac_device_handle_ce(dci, 0, 0, drvdata->edac_dev_name);
569 ret_value = IRQ_HANDLED;
570 } else if (irq == drvdata->db_irq) {
571 if (priv->ue_clear_mask)
572 writel(priv->ue_clear_mask, drvdata->base);
573 edac_device_handle_ue(dci, 0, 0, drvdata->edac_dev_name);
574 panic("\nEDAC:ECC_DEVICE[Uncorrectable errors]\n");
575 ret_value = IRQ_HANDLED;
576 } else {
577 WARN_ON(1);
578 }
579
580 return ret_value;
581}
582
583static ssize_t altr_edac_device_trig(struct file *file,
584 const char __user *user_buf,
585 size_t count, loff_t *ppos)
586
587{
588 u32 *ptemp, i, error_mask;
589 int result = 0;
590 u8 trig_type;
591 unsigned long flags;
592 struct edac_device_ctl_info *edac_dci = file->private_data;
593 struct altr_edac_device_dev *drvdata = edac_dci->pvt_info;
594 const struct edac_device_prv_data *priv = drvdata->data;
595 void *generic_ptr = edac_dci->dev;
596
597 if (!user_buf || get_user(trig_type, user_buf))
598 return -EFAULT;
599
600 if (!priv->alloc_mem)
601 return -ENOMEM;
602
603 /*
604 * Note that generic_ptr is initialized to the device * but in
605 * some alloc_functions, this is overridden and returns data.
606 */
607 ptemp = priv->alloc_mem(priv->trig_alloc_sz, &generic_ptr);
608 if (!ptemp) {
609 edac_printk(KERN_ERR, EDAC_DEVICE,
610 "Inject: Buffer Allocation error\n");
611 return -ENOMEM;
612 }
613
614 if (trig_type == ALTR_UE_TRIGGER_CHAR)
615 error_mask = priv->ue_set_mask;
616 else
617 error_mask = priv->ce_set_mask;
618
619 edac_printk(KERN_ALERT, EDAC_DEVICE,
620 "Trigger Error Mask (0x%X)\n", error_mask);
621
622 local_irq_save(flags);
623 /* write ECC corrupted data out. */
624 for (i = 0; i < (priv->trig_alloc_sz / sizeof(*ptemp)); i++) {
625 /* Read data so we're in the correct state */
626 rmb();
627 if (ACCESS_ONCE(ptemp[i]))
628 result = -1;
629 /* Toggle Error bit (it is latched), leave ECC enabled */
Thor Thayer811fce42016-03-21 11:01:42 -0500630 writel(error_mask, (drvdata->base + priv->set_err_ofst));
631 writel(priv->ecc_enable_mask, (drvdata->base +
632 priv->set_err_ofst));
Thor Thayerc3eea192016-02-10 13:26:21 -0600633 ptemp[i] = i;
634 }
635 /* Ensure it has been written out */
636 wmb();
637 local_irq_restore(flags);
638
639 if (result)
640 edac_printk(KERN_ERR, EDAC_DEVICE, "Mem Not Cleared\n");
641
642 /* Read out written data. ECC error caused here */
643 for (i = 0; i < ALTR_TRIGGER_READ_WRD_CNT; i++)
644 if (ACCESS_ONCE(ptemp[i]) != i)
645 edac_printk(KERN_ERR, EDAC_DEVICE,
646 "Read doesn't match written data\n");
647
648 if (priv->free_mem)
649 priv->free_mem(ptemp, priv->trig_alloc_sz, generic_ptr);
650
651 return count;
652}
653
654static const struct file_operations altr_edac_device_inject_fops = {
655 .open = simple_open,
656 .write = altr_edac_device_trig,
657 .llseek = generic_file_llseek,
658};
659
Thor Thayerc7b4be82016-04-06 20:22:54 -0500660static ssize_t altr_edac_a10_device_trig(struct file *file,
661 const char __user *user_buf,
662 size_t count, loff_t *ppos);
663
664static const struct file_operations altr_edac_a10_device_inject_fops = {
665 .open = simple_open,
666 .write = altr_edac_a10_device_trig,
667 .llseek = generic_file_llseek,
668};
669
Thor Thayerc3eea192016-02-10 13:26:21 -0600670static void altr_create_edacdev_dbgfs(struct edac_device_ctl_info *edac_dci,
671 const struct edac_device_prv_data *priv)
672{
673 struct altr_edac_device_dev *drvdata = edac_dci->pvt_info;
674
675 if (!IS_ENABLED(CONFIG_EDAC_DEBUG))
676 return;
677
678 drvdata->debugfs_dir = edac_debugfs_create_dir(drvdata->edac_dev_name);
679 if (!drvdata->debugfs_dir)
680 return;
681
682 if (!edac_debugfs_create_file(priv->dbgfs_name, S_IWUSR,
683 drvdata->debugfs_dir, edac_dci,
Thor Thayere17ced22016-03-31 13:48:01 -0500684 priv->inject_fops))
Thor Thayerc3eea192016-02-10 13:26:21 -0600685 debugfs_remove_recursive(drvdata->debugfs_dir);
686}
687
688static const struct of_device_id altr_edac_device_of_match[] = {
689#ifdef CONFIG_EDAC_ALTERA_L2C
Arnd Bergmann2c911f62016-04-16 22:13:55 +0200690 { .compatible = "altr,socfpga-l2-ecc", .data = &l2ecc_data },
Thor Thayerc3eea192016-02-10 13:26:21 -0600691#endif
692#ifdef CONFIG_EDAC_ALTERA_OCRAM
Arnd Bergmann2c911f62016-04-16 22:13:55 +0200693 { .compatible = "altr,socfpga-ocram-ecc", .data = &ocramecc_data },
Thor Thayerc3eea192016-02-10 13:26:21 -0600694#endif
695 {},
696};
697MODULE_DEVICE_TABLE(of, altr_edac_device_of_match);
698
699/*
700 * altr_edac_device_probe()
701 * This is a generic EDAC device driver that will support
702 * various Altera memory devices such as the L2 cache ECC and
703 * OCRAM ECC as well as the memories for other peripherals.
704 * Module specific initialization is done by passing the
705 * function index in the device tree.
706 */
707static int altr_edac_device_probe(struct platform_device *pdev)
708{
709 struct edac_device_ctl_info *dci;
710 struct altr_edac_device_dev *drvdata;
711 struct resource *r;
712 int res = 0;
713 struct device_node *np = pdev->dev.of_node;
714 char *ecc_name = (char *)np->name;
715 static int dev_instance;
716
717 if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL)) {
718 edac_printk(KERN_ERR, EDAC_DEVICE,
719 "Unable to open devm\n");
720 return -ENOMEM;
721 }
722
723 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
724 if (!r) {
725 edac_printk(KERN_ERR, EDAC_DEVICE,
726 "Unable to get mem resource\n");
727 res = -ENODEV;
728 goto fail;
729 }
730
731 if (!devm_request_mem_region(&pdev->dev, r->start, resource_size(r),
732 dev_name(&pdev->dev))) {
733 edac_printk(KERN_ERR, EDAC_DEVICE,
734 "%s:Error requesting mem region\n", ecc_name);
735 res = -EBUSY;
736 goto fail;
737 }
738
739 dci = edac_device_alloc_ctl_info(sizeof(*drvdata), ecc_name,
740 1, ecc_name, 1, 0, NULL, 0,
741 dev_instance++);
742
743 if (!dci) {
744 edac_printk(KERN_ERR, EDAC_DEVICE,
745 "%s: Unable to allocate EDAC device\n", ecc_name);
746 res = -ENOMEM;
747 goto fail;
748 }
749
750 drvdata = dci->pvt_info;
751 dci->dev = &pdev->dev;
752 platform_set_drvdata(pdev, dci);
753 drvdata->edac_dev_name = ecc_name;
754
755 drvdata->base = devm_ioremap(&pdev->dev, r->start, resource_size(r));
756 if (!drvdata->base)
757 goto fail1;
758
759 /* Get driver specific data for this EDAC device */
760 drvdata->data = of_match_node(altr_edac_device_of_match, np)->data;
761
762 /* Check specific dependencies for the module */
763 if (drvdata->data->setup) {
Thor Thayer328ca7a2016-03-21 11:01:40 -0500764 res = drvdata->data->setup(drvdata);
Thor Thayerc3eea192016-02-10 13:26:21 -0600765 if (res)
766 goto fail1;
767 }
768
769 drvdata->sb_irq = platform_get_irq(pdev, 0);
770 res = devm_request_irq(&pdev->dev, drvdata->sb_irq,
771 altr_edac_device_handler,
772 0, dev_name(&pdev->dev), dci);
773 if (res)
774 goto fail1;
775
776 drvdata->db_irq = platform_get_irq(pdev, 1);
777 res = devm_request_irq(&pdev->dev, drvdata->db_irq,
778 altr_edac_device_handler,
779 0, dev_name(&pdev->dev), dci);
780 if (res)
781 goto fail1;
782
783 dci->mod_name = "Altera ECC Manager";
784 dci->dev_name = drvdata->edac_dev_name;
785
786 res = edac_device_add_device(dci);
787 if (res)
788 goto fail1;
789
790 altr_create_edacdev_dbgfs(dci, drvdata->data);
791
792 devres_close_group(&pdev->dev, NULL);
793
794 return 0;
795
796fail1:
797 edac_device_free_ctl_info(dci);
798fail:
799 devres_release_group(&pdev->dev, NULL);
800 edac_printk(KERN_ERR, EDAC_DEVICE,
801 "%s:Error setting up EDAC device: %d\n", ecc_name, res);
802
803 return res;
804}
805
806static int altr_edac_device_remove(struct platform_device *pdev)
807{
808 struct edac_device_ctl_info *dci = platform_get_drvdata(pdev);
809 struct altr_edac_device_dev *drvdata = dci->pvt_info;
810
811 debugfs_remove_recursive(drvdata->debugfs_dir);
812 edac_device_del_device(&pdev->dev);
813 edac_device_free_ctl_info(dci);
814
815 return 0;
816}
817
818static struct platform_driver altr_edac_device_driver = {
819 .probe = altr_edac_device_probe,
820 .remove = altr_edac_device_remove,
821 .driver = {
822 .name = "altr_edac_device",
823 .of_match_table = altr_edac_device_of_match,
824 },
825};
826module_platform_driver(altr_edac_device_driver);
827
828/*********************** OCRAM EDAC Device Functions *********************/
829
830#ifdef CONFIG_EDAC_ALTERA_OCRAM
Arnd Bergmann1aa6eb52016-04-16 22:13:56 +0200831/*
832 * Test for memory's ECC dependencies upon entry because platform specific
833 * startup should have initialized the memory and enabled the ECC.
834 * Can't turn on ECC here because accessing un-initialized memory will
835 * cause CE/UE errors possibly causing an ABORT.
836 */
837static int altr_check_ecc_deps(struct altr_edac_device_dev *device)
838{
839 void __iomem *base = device->base;
840 const struct edac_device_prv_data *prv = device->data;
841
842 if (readl(base + prv->ecc_en_ofst) & prv->ecc_enable_mask)
843 return 0;
844
845 edac_printk(KERN_ERR, EDAC_DEVICE,
846 "%s: No ECC present or ECC disabled.\n",
847 device->edac_dev_name);
848 return -ENODEV;
849}
Thor Thayerc3eea192016-02-10 13:26:21 -0600850
851static void *ocram_alloc_mem(size_t size, void **other)
852{
853 struct device_node *np;
854 struct gen_pool *gp;
855 void *sram_addr;
856
857 np = of_find_compatible_node(NULL, NULL, "altr,socfpga-ocram-ecc");
858 if (!np)
859 return NULL;
860
861 gp = of_gen_pool_get(np, "iram", 0);
862 of_node_put(np);
863 if (!gp)
864 return NULL;
865
866 sram_addr = (void *)gen_pool_alloc(gp, size);
867 if (!sram_addr)
868 return NULL;
869
870 memset(sram_addr, 0, size);
871 /* Ensure data is written out */
872 wmb();
873
874 /* Remember this handle for freeing later */
875 *other = gp;
876
877 return sram_addr;
878}
879
880static void ocram_free_mem(void *p, size_t size, void *other)
881{
882 gen_pool_free((struct gen_pool *)other, (u32)p, size);
883}
884
Thor Thayer13ab8442016-06-07 15:35:57 -0500885static irqreturn_t altr_edac_a10_ecc_irq(int irq, void *dev_id)
Arnd Bergmann1aa6eb52016-04-16 22:13:56 +0200886{
Thor Thayer13ab8442016-06-07 15:35:57 -0500887 struct altr_edac_device_dev *dci = dev_id;
Arnd Bergmann1aa6eb52016-04-16 22:13:56 +0200888 void __iomem *base = dci->base;
889
Thor Thayer13ab8442016-06-07 15:35:57 -0500890 if (irq == dci->sb_irq) {
Arnd Bergmann1aa6eb52016-04-16 22:13:56 +0200891 writel(ALTR_A10_ECC_SERRPENA,
892 base + ALTR_A10_ECC_INTSTAT_OFST);
893 edac_device_handle_ce(dci->edac_dev, 0, 0, dci->edac_dev_name);
Thor Thayer13ab8442016-06-07 15:35:57 -0500894
895 return IRQ_HANDLED;
896 } else if (irq == dci->db_irq) {
Arnd Bergmann1aa6eb52016-04-16 22:13:56 +0200897 writel(ALTR_A10_ECC_DERRPENA,
898 base + ALTR_A10_ECC_INTSTAT_OFST);
899 edac_device_handle_ue(dci->edac_dev, 0, 0, dci->edac_dev_name);
900 panic("\nEDAC:ECC_DEVICE[Uncorrectable errors]\n");
Thor Thayer13ab8442016-06-07 15:35:57 -0500901
902 return IRQ_HANDLED;
Arnd Bergmann1aa6eb52016-04-16 22:13:56 +0200903 }
Thor Thayer13ab8442016-06-07 15:35:57 -0500904
905 WARN_ON(1);
906
907 return IRQ_NONE;
Arnd Bergmann1aa6eb52016-04-16 22:13:56 +0200908}
909
Thor Thayerc3eea192016-02-10 13:26:21 -0600910const struct edac_device_prv_data ocramecc_data = {
Thor Thayeraa1f06d2016-03-31 13:48:03 -0500911 .setup = altr_check_ecc_deps,
Thor Thayerc3eea192016-02-10 13:26:21 -0600912 .ce_clear_mask = (ALTR_OCR_ECC_EN | ALTR_OCR_ECC_SERR),
913 .ue_clear_mask = (ALTR_OCR_ECC_EN | ALTR_OCR_ECC_DERR),
914 .dbgfs_name = "altr_ocram_trigger",
915 .alloc_mem = ocram_alloc_mem,
916 .free_mem = ocram_free_mem,
917 .ecc_enable_mask = ALTR_OCR_ECC_EN,
Thor Thayer943ad912016-03-31 13:48:02 -0500918 .ecc_en_ofst = ALTR_OCR_ECC_REG_OFFSET,
Thor Thayerc3eea192016-02-10 13:26:21 -0600919 .ce_set_mask = (ALTR_OCR_ECC_EN | ALTR_OCR_ECC_INJS),
920 .ue_set_mask = (ALTR_OCR_ECC_EN | ALTR_OCR_ECC_INJD),
Thor Thayer811fce42016-03-21 11:01:42 -0500921 .set_err_ofst = ALTR_OCR_ECC_REG_OFFSET,
Thor Thayerc3eea192016-02-10 13:26:21 -0600922 .trig_alloc_sz = ALTR_TRIG_OCRAM_BYTE_SIZE,
Thor Thayere17ced22016-03-31 13:48:01 -0500923 .inject_fops = &altr_edac_device_inject_fops,
Thor Thayerc3eea192016-02-10 13:26:21 -0600924};
925
Thor Thayerc7b4be82016-04-06 20:22:54 -0500926const struct edac_device_prv_data a10_ocramecc_data = {
927 .setup = altr_check_ecc_deps,
928 .ce_clear_mask = ALTR_A10_ECC_SERRPENA,
929 .ue_clear_mask = ALTR_A10_ECC_DERRPENA,
930 .irq_status_mask = A10_SYSMGR_ECC_INTSTAT_OCRAM,
931 .dbgfs_name = "altr_ocram_trigger",
932 .ecc_enable_mask = ALTR_A10_OCRAM_ECC_EN_CTL,
933 .ecc_en_ofst = ALTR_A10_ECC_CTRL_OFST,
934 .ce_set_mask = ALTR_A10_ECC_TSERRA,
935 .ue_set_mask = ALTR_A10_ECC_TDERRA,
936 .set_err_ofst = ALTR_A10_ECC_INTTEST_OFST,
937 .ecc_irq_handler = altr_edac_a10_ecc_irq,
938 .inject_fops = &altr_edac_a10_device_inject_fops,
939};
940
Thor Thayerc3eea192016-02-10 13:26:21 -0600941#endif /* CONFIG_EDAC_ALTERA_OCRAM */
942
943/********************* L2 Cache EDAC Device Functions ********************/
944
945#ifdef CONFIG_EDAC_ALTERA_L2C
946
947static void *l2_alloc_mem(size_t size, void **other)
948{
949 struct device *dev = *other;
950 void *ptemp = devm_kzalloc(dev, size, GFP_KERNEL);
951
952 if (!ptemp)
953 return NULL;
954
955 /* Make sure everything is written out */
956 wmb();
957
958 /*
959 * Clean all cache levels up to LoC (includes L2)
960 * This ensures the corrupted data is written into
961 * L2 cache for readback test (which causes ECC error).
962 */
963 flush_cache_all();
964
965 return ptemp;
966}
967
968static void l2_free_mem(void *p, size_t size, void *other)
969{
970 struct device *dev = other;
971
972 if (dev && p)
973 devm_kfree(dev, p);
974}
975
976/*
977 * altr_l2_check_deps()
978 * Test for L2 cache ECC dependencies upon entry because
979 * platform specific startup should have initialized the L2
980 * memory and enabled the ECC.
981 * Bail if ECC is not enabled.
982 * Note that L2 Cache Enable is forced at build time.
983 */
Thor Thayer328ca7a2016-03-21 11:01:40 -0500984static int altr_l2_check_deps(struct altr_edac_device_dev *device)
Thor Thayerc3eea192016-02-10 13:26:21 -0600985{
Thor Thayer328ca7a2016-03-21 11:01:40 -0500986 void __iomem *base = device->base;
Thor Thayer27439a12016-03-21 11:01:41 -0500987 const struct edac_device_prv_data *prv = device->data;
988
989 if ((readl(base) & prv->ecc_enable_mask) ==
990 prv->ecc_enable_mask)
Thor Thayerc3eea192016-02-10 13:26:21 -0600991 return 0;
992
993 edac_printk(KERN_ERR, EDAC_DEVICE,
994 "L2: No ECC present, or ECC disabled\n");
995 return -ENODEV;
996}
997
Thor Thayer13ab8442016-06-07 15:35:57 -0500998static irqreturn_t altr_edac_a10_l2_irq(int irq, void *dev_id)
Thor Thayer588cb032016-03-21 11:01:44 -0500999{
Thor Thayer13ab8442016-06-07 15:35:57 -05001000 struct altr_edac_device_dev *dci = dev_id;
1001
1002 if (irq == dci->sb_irq) {
Thor Thayer588cb032016-03-21 11:01:44 -05001003 regmap_write(dci->edac->ecc_mgr_map,
1004 A10_SYSGMR_MPU_CLEAR_L2_ECC_OFST,
1005 A10_SYSGMR_MPU_CLEAR_L2_ECC_SB);
1006 edac_device_handle_ce(dci->edac_dev, 0, 0, dci->edac_dev_name);
Thor Thayer13ab8442016-06-07 15:35:57 -05001007
1008 return IRQ_HANDLED;
1009 } else if (irq == dci->db_irq) {
Thor Thayer588cb032016-03-21 11:01:44 -05001010 regmap_write(dci->edac->ecc_mgr_map,
1011 A10_SYSGMR_MPU_CLEAR_L2_ECC_OFST,
1012 A10_SYSGMR_MPU_CLEAR_L2_ECC_MB);
1013 edac_device_handle_ue(dci->edac_dev, 0, 0, dci->edac_dev_name);
1014 panic("\nEDAC:ECC_DEVICE[Uncorrectable errors]\n");
Thor Thayer13ab8442016-06-07 15:35:57 -05001015
1016 return IRQ_HANDLED;
Thor Thayer588cb032016-03-21 11:01:44 -05001017 }
Thor Thayer13ab8442016-06-07 15:35:57 -05001018
1019 WARN_ON(1);
1020
1021 return IRQ_NONE;
Thor Thayer588cb032016-03-21 11:01:44 -05001022}
1023
Thor Thayerc3eea192016-02-10 13:26:21 -06001024const struct edac_device_prv_data l2ecc_data = {
1025 .setup = altr_l2_check_deps,
1026 .ce_clear_mask = 0,
1027 .ue_clear_mask = 0,
1028 .dbgfs_name = "altr_l2_trigger",
1029 .alloc_mem = l2_alloc_mem,
1030 .free_mem = l2_free_mem,
1031 .ecc_enable_mask = ALTR_L2_ECC_EN,
1032 .ce_set_mask = (ALTR_L2_ECC_EN | ALTR_L2_ECC_INJS),
1033 .ue_set_mask = (ALTR_L2_ECC_EN | ALTR_L2_ECC_INJD),
Thor Thayer811fce42016-03-21 11:01:42 -05001034 .set_err_ofst = ALTR_L2_ECC_REG_OFFSET,
Thor Thayerc3eea192016-02-10 13:26:21 -06001035 .trig_alloc_sz = ALTR_TRIG_L2C_BYTE_SIZE,
Thor Thayere17ced22016-03-31 13:48:01 -05001036 .inject_fops = &altr_edac_device_inject_fops,
Thor Thayerc3eea192016-02-10 13:26:21 -06001037};
1038
Thor Thayer588cb032016-03-21 11:01:44 -05001039const struct edac_device_prv_data a10_l2ecc_data = {
1040 .setup = altr_l2_check_deps,
1041 .ce_clear_mask = ALTR_A10_L2_ECC_SERR_CLR,
1042 .ue_clear_mask = ALTR_A10_L2_ECC_MERR_CLR,
1043 .irq_status_mask = A10_SYSMGR_ECC_INTSTAT_L2,
1044 .dbgfs_name = "altr_l2_trigger",
1045 .alloc_mem = l2_alloc_mem,
1046 .free_mem = l2_free_mem,
1047 .ecc_enable_mask = ALTR_A10_L2_ECC_EN_CTL,
1048 .ce_set_mask = ALTR_A10_L2_ECC_CE_INJ_MASK,
1049 .ue_set_mask = ALTR_A10_L2_ECC_UE_INJ_MASK,
1050 .set_err_ofst = ALTR_A10_L2_ECC_INJ_OFST,
1051 .ecc_irq_handler = altr_edac_a10_l2_irq,
1052 .trig_alloc_sz = ALTR_TRIG_L2C_BYTE_SIZE,
Thor Thayere17ced22016-03-31 13:48:01 -05001053 .inject_fops = &altr_edac_device_inject_fops,
Thor Thayer588cb032016-03-21 11:01:44 -05001054};
1055
Thor Thayerc3eea192016-02-10 13:26:21 -06001056#endif /* CONFIG_EDAC_ALTERA_L2C */
1057
Thor Thayer588cb032016-03-21 11:01:44 -05001058/********************* Arria10 EDAC Device Functions *************************/
Thor Thayerab564cb2016-05-25 11:29:41 -05001059static const struct of_device_id altr_edac_a10_device_of_match[] = {
1060#ifdef CONFIG_EDAC_ALTERA_L2C
1061 { .compatible = "altr,socfpga-a10-l2-ecc", .data = &a10_l2ecc_data },
1062#endif
1063#ifdef CONFIG_EDAC_ALTERA_OCRAM
1064 { .compatible = "altr,socfpga-a10-ocram-ecc",
1065 .data = &a10_ocramecc_data },
1066#endif
1067 {},
1068};
1069MODULE_DEVICE_TABLE(of, altr_edac_a10_device_of_match);
Thor Thayer588cb032016-03-21 11:01:44 -05001070
1071/*
1072 * The Arria10 EDAC Device Functions differ from the Cyclone5/Arria5
1073 * because 2 IRQs are shared among the all ECC peripherals. The ECC
1074 * manager manages the IRQs and the children.
1075 * Based on xgene_edac.c peripheral code.
1076 */
1077
Thor Thayerc7b4be82016-04-06 20:22:54 -05001078static ssize_t altr_edac_a10_device_trig(struct file *file,
1079 const char __user *user_buf,
1080 size_t count, loff_t *ppos)
1081{
1082 struct edac_device_ctl_info *edac_dci = file->private_data;
1083 struct altr_edac_device_dev *drvdata = edac_dci->pvt_info;
1084 const struct edac_device_prv_data *priv = drvdata->data;
1085 void __iomem *set_addr = (drvdata->base + priv->set_err_ofst);
1086 unsigned long flags;
1087 u8 trig_type;
1088
1089 if (!user_buf || get_user(trig_type, user_buf))
1090 return -EFAULT;
1091
1092 local_irq_save(flags);
1093 if (trig_type == ALTR_UE_TRIGGER_CHAR)
1094 writel(priv->ue_set_mask, set_addr);
1095 else
1096 writel(priv->ce_set_mask, set_addr);
1097 /* Ensure the interrupt test bits are set */
1098 wmb();
1099 local_irq_restore(flags);
1100
1101 return count;
1102}
1103
Thor Thayer13ab8442016-06-07 15:35:57 -05001104static void altr_edac_a10_irq_handler(struct irq_desc *desc)
Thor Thayer588cb032016-03-21 11:01:44 -05001105{
Thor Thayer13ab8442016-06-07 15:35:57 -05001106 int dberr, bit, sm_offset, irq_status;
1107 struct altr_arria10_edac *edac = irq_desc_get_handler_data(desc);
1108 struct irq_chip *chip = irq_desc_get_chip(desc);
1109 int irq = irq_desc_get_irq(desc);
1110
1111 dberr = (irq == edac->db_irq) ? 1 : 0;
1112 sm_offset = dberr ? A10_SYSMGR_ECC_INTSTAT_DERR_OFST :
1113 A10_SYSMGR_ECC_INTSTAT_SERR_OFST;
1114
1115 chained_irq_enter(chip, desc);
Thor Thayer588cb032016-03-21 11:01:44 -05001116
1117 regmap_read(edac->ecc_mgr_map, sm_offset, &irq_status);
1118
Thor Thayer13ab8442016-06-07 15:35:57 -05001119 for_each_set_bit(bit, (unsigned long *)&irq_status, 32) {
1120 irq = irq_linear_revmap(edac->domain, dberr * 32 + bit);
1121 if (irq)
1122 generic_handle_irq(irq);
Thor Thayer588cb032016-03-21 11:01:44 -05001123 }
1124
Thor Thayer13ab8442016-06-07 15:35:57 -05001125 chained_irq_exit(chip, desc);
Thor Thayer588cb032016-03-21 11:01:44 -05001126}
1127
1128static int altr_edac_a10_device_add(struct altr_arria10_edac *edac,
1129 struct device_node *np)
1130{
1131 struct edac_device_ctl_info *dci;
1132 struct altr_edac_device_dev *altdev;
1133 char *ecc_name = (char *)np->name;
1134 struct resource res;
1135 int edac_idx;
1136 int rc = 0;
1137 const struct edac_device_prv_data *prv;
1138 /* Get matching node and check for valid result */
1139 const struct of_device_id *pdev_id =
Thor Thayerab564cb2016-05-25 11:29:41 -05001140 of_match_node(altr_edac_a10_device_of_match, np);
Thor Thayer588cb032016-03-21 11:01:44 -05001141 if (IS_ERR_OR_NULL(pdev_id))
1142 return -ENODEV;
1143
1144 /* Get driver specific data for this EDAC device */
1145 prv = pdev_id->data;
1146 if (IS_ERR_OR_NULL(prv))
1147 return -ENODEV;
1148
1149 if (!devres_open_group(edac->dev, altr_edac_a10_device_add, GFP_KERNEL))
1150 return -ENOMEM;
1151
1152 rc = of_address_to_resource(np, 0, &res);
1153 if (rc < 0) {
1154 edac_printk(KERN_ERR, EDAC_DEVICE,
1155 "%s: no resource address\n", ecc_name);
1156 goto err_release_group;
1157 }
1158
1159 edac_idx = edac_device_alloc_index();
1160 dci = edac_device_alloc_ctl_info(sizeof(*altdev), ecc_name,
1161 1, ecc_name, 1, 0, NULL, 0,
1162 edac_idx);
1163
1164 if (!dci) {
1165 edac_printk(KERN_ERR, EDAC_DEVICE,
1166 "%s: Unable to allocate EDAC device\n", ecc_name);
1167 rc = -ENOMEM;
1168 goto err_release_group;
1169 }
1170
1171 altdev = dci->pvt_info;
1172 dci->dev = edac->dev;
1173 altdev->edac_dev_name = ecc_name;
1174 altdev->edac_idx = edac_idx;
1175 altdev->edac = edac;
1176 altdev->edac_dev = dci;
1177 altdev->data = prv;
1178 altdev->ddev = *edac->dev;
1179 dci->dev = &altdev->ddev;
1180 dci->ctl_name = "Altera ECC Manager";
1181 dci->mod_name = ecc_name;
1182 dci->dev_name = ecc_name;
1183
1184 altdev->base = devm_ioremap_resource(edac->dev, &res);
1185 if (IS_ERR(altdev->base)) {
1186 rc = PTR_ERR(altdev->base);
1187 goto err_release_group1;
1188 }
1189
1190 /* Check specific dependencies for the module */
1191 if (altdev->data->setup) {
1192 rc = altdev->data->setup(altdev);
1193 if (rc)
1194 goto err_release_group1;
1195 }
1196
Thor Thayer13ab8442016-06-07 15:35:57 -05001197 altdev->sb_irq = irq_of_parse_and_map(np, 0);
1198 if (!altdev->sb_irq) {
1199 edac_printk(KERN_ERR, EDAC_DEVICE, "Error allocating SBIRQ\n");
1200 rc = -ENODEV;
1201 goto err_release_group1;
1202 }
1203 rc = devm_request_irq(edac->dev, altdev->sb_irq,
1204 prv->ecc_irq_handler,
1205 IRQF_SHARED, ecc_name, altdev);
1206 if (rc) {
1207 edac_printk(KERN_ERR, EDAC_DEVICE, "No DBERR IRQ resource\n");
1208 goto err_release_group1;
1209 }
1210
1211 altdev->db_irq = irq_of_parse_and_map(np, 1);
1212 if (!altdev->db_irq) {
1213 edac_printk(KERN_ERR, EDAC_DEVICE, "Error allocating DBIRQ\n");
1214 rc = -ENODEV;
1215 goto err_release_group1;
1216 }
1217 rc = devm_request_irq(edac->dev, altdev->db_irq,
1218 prv->ecc_irq_handler,
1219 IRQF_SHARED, ecc_name, altdev);
1220 if (rc) {
1221 edac_printk(KERN_ERR, EDAC_DEVICE, "No DBERR IRQ resource\n");
1222 goto err_release_group1;
1223 }
1224
Thor Thayer588cb032016-03-21 11:01:44 -05001225 rc = edac_device_add_device(dci);
1226 if (rc) {
1227 dev_err(edac->dev, "edac_device_add_device failed\n");
1228 rc = -ENOMEM;
1229 goto err_release_group1;
1230 }
1231
1232 altr_create_edacdev_dbgfs(dci, prv);
1233
1234 list_add(&altdev->next, &edac->a10_ecc_devices);
1235
1236 devres_remove_group(edac->dev, altr_edac_a10_device_add);
1237
1238 return 0;
1239
1240err_release_group1:
1241 edac_device_free_ctl_info(dci);
1242err_release_group:
Thor Thayer588cb032016-03-21 11:01:44 -05001243 devres_release_group(edac->dev, NULL);
1244 edac_printk(KERN_ERR, EDAC_DEVICE,
1245 "%s:Error setting up EDAC device: %d\n", ecc_name, rc);
1246
1247 return rc;
1248}
1249
Thor Thayer13ab8442016-06-07 15:35:57 -05001250static void a10_eccmgr_irq_mask(struct irq_data *d)
1251{
1252 struct altr_arria10_edac *edac = irq_data_get_irq_chip_data(d);
1253
1254 regmap_write(edac->ecc_mgr_map, A10_SYSMGR_ECC_INTMASK_SET_OFST,
1255 BIT(d->hwirq));
1256}
1257
1258static void a10_eccmgr_irq_unmask(struct irq_data *d)
1259{
1260 struct altr_arria10_edac *edac = irq_data_get_irq_chip_data(d);
1261
1262 regmap_write(edac->ecc_mgr_map, A10_SYSMGR_ECC_INTMASK_CLR_OFST,
1263 BIT(d->hwirq));
1264}
1265
1266static int a10_eccmgr_irqdomain_map(struct irq_domain *d, unsigned int irq,
1267 irq_hw_number_t hwirq)
1268{
1269 struct altr_arria10_edac *edac = d->host_data;
1270
1271 irq_set_chip_and_handler(irq, &edac->irq_chip, handle_simple_irq);
1272 irq_set_chip_data(irq, edac);
1273 irq_set_noprobe(irq);
1274
1275 return 0;
1276}
1277
1278struct irq_domain_ops a10_eccmgr_ic_ops = {
1279 .map = a10_eccmgr_irqdomain_map,
1280 .xlate = irq_domain_xlate_twocell,
1281};
1282
Thor Thayer588cb032016-03-21 11:01:44 -05001283static int altr_edac_a10_probe(struct platform_device *pdev)
1284{
1285 struct altr_arria10_edac *edac;
1286 struct device_node *child;
Thor Thayer588cb032016-03-21 11:01:44 -05001287
1288 edac = devm_kzalloc(&pdev->dev, sizeof(*edac), GFP_KERNEL);
1289 if (!edac)
1290 return -ENOMEM;
1291
1292 edac->dev = &pdev->dev;
1293 platform_set_drvdata(pdev, edac);
1294 INIT_LIST_HEAD(&edac->a10_ecc_devices);
1295
1296 edac->ecc_mgr_map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
1297 "altr,sysmgr-syscon");
1298 if (IS_ERR(edac->ecc_mgr_map)) {
1299 edac_printk(KERN_ERR, EDAC_DEVICE,
1300 "Unable to get syscon altr,sysmgr-syscon\n");
1301 return PTR_ERR(edac->ecc_mgr_map);
1302 }
1303
Thor Thayer13ab8442016-06-07 15:35:57 -05001304 edac->irq_chip.name = pdev->dev.of_node->name;
1305 edac->irq_chip.irq_mask = a10_eccmgr_irq_mask;
1306 edac->irq_chip.irq_unmask = a10_eccmgr_irq_unmask;
1307 edac->domain = irq_domain_add_linear(pdev->dev.of_node, 64,
1308 &a10_eccmgr_ic_ops, edac);
1309 if (!edac->domain) {
1310 dev_err(&pdev->dev, "Error adding IRQ domain\n");
1311 return -ENOMEM;
Thor Thayer588cb032016-03-21 11:01:44 -05001312 }
1313
Thor Thayer13ab8442016-06-07 15:35:57 -05001314 edac->sb_irq = platform_get_irq(pdev, 0);
1315 if (edac->sb_irq < 0) {
1316 dev_err(&pdev->dev, "No SBERR IRQ resource\n");
1317 return edac->sb_irq;
Thor Thayer588cb032016-03-21 11:01:44 -05001318 }
1319
Thor Thayer13ab8442016-06-07 15:35:57 -05001320 irq_set_chained_handler_and_data(edac->sb_irq,
1321 altr_edac_a10_irq_handler,
1322 edac);
1323
1324 edac->db_irq = platform_get_irq(pdev, 1);
1325 if (edac->db_irq < 0) {
1326 dev_err(&pdev->dev, "No DBERR IRQ resource\n");
1327 return edac->db_irq;
1328 }
1329 irq_set_chained_handler_and_data(edac->db_irq,
1330 altr_edac_a10_irq_handler,
1331 edac);
1332
Thor Thayer588cb032016-03-21 11:01:44 -05001333 for_each_child_of_node(pdev->dev.of_node, child) {
1334 if (!of_device_is_available(child))
1335 continue;
1336 if (of_device_is_compatible(child, "altr,socfpga-a10-l2-ecc"))
1337 altr_edac_a10_device_add(edac, child);
Thor Thayerc7b4be82016-04-06 20:22:54 -05001338 else if (of_device_is_compatible(child,
1339 "altr,socfpga-a10-ocram-ecc"))
1340 altr_edac_a10_device_add(edac, child);
Thor Thayerab564cb2016-05-25 11:29:41 -05001341 else if (of_device_is_compatible(child,
1342 "altr,sdram-edac-a10"))
1343 of_platform_populate(pdev->dev.of_node,
1344 altr_sdram_ctrl_of_match,
1345 NULL, &pdev->dev);
Thor Thayer588cb032016-03-21 11:01:44 -05001346 }
1347
1348 return 0;
1349}
1350
1351static const struct of_device_id altr_edac_a10_of_match[] = {
1352 { .compatible = "altr,socfpga-a10-ecc-manager" },
1353 {},
1354};
1355MODULE_DEVICE_TABLE(of, altr_edac_a10_of_match);
1356
1357static struct platform_driver altr_edac_a10_driver = {
1358 .probe = altr_edac_a10_probe,
1359 .driver = {
1360 .name = "socfpga_a10_ecc_manager",
1361 .of_match_table = altr_edac_a10_of_match,
1362 },
1363};
1364module_platform_driver(altr_edac_a10_driver);
1365
Thor Thayer71bcada2014-09-03 10:27:54 -05001366MODULE_LICENSE("GPL v2");
1367MODULE_AUTHOR("Thor Thayer");
Thor Thayerc3eea192016-02-10 13:26:21 -06001368MODULE_DESCRIPTION("EDAC Driver for Altera Memories");