1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include <linux/edac.h>
23#include <linux/module.h>
24#include <linux/platform_device.h>
25#include <linux/interrupt.h>
26#include <linux/of.h>
27
28#include "edac_core.h"
29
30
31#define SYNPS_EDAC_NR_CSROWS 1
32
33
34#define SYNPS_EDAC_NR_CHANS 1
35
36
37#define SYNPS_EDAC_ERR_GRAIN 1
38
39#define SYNPS_EDAC_MSG_SIZE 256
40
41#define SYNPS_EDAC_MOD_STRING "synps_edac"
42#define SYNPS_EDAC_MOD_VER "1"
43
44
45#define CTRL_OFST 0x0
46#define T_ZQ_OFST 0xA4
47
48
49#define ECC_CTRL_OFST 0xC4
50
51#define CE_LOG_OFST 0xC8
52
53#define CE_ADDR_OFST 0xCC
54
55#define CE_DATA_31_0_OFST 0xD0
56
57
58#define UE_LOG_OFST 0xDC
59#define UE_ADDR_OFST 0xE0
60#define UE_DATA_31_0_OFST 0xE4
61
62#define STAT_OFST 0xF0
63#define SCRUB_OFST 0xF4
64
65
66#define CTRL_BW_MASK 0xC
67#define CTRL_BW_SHIFT 2
68
69#define DDRCTL_WDTH_16 1
70#define DDRCTL_WDTH_32 0
71
72
73#define T_ZQ_DDRMODE_MASK 0x2
74
75
76#define ECC_CTRL_CLR_CE_ERR 0x2
77#define ECC_CTRL_CLR_UE_ERR 0x1
78
79
80#define LOG_VALID 0x1
81#define CE_LOG_BITPOS_MASK 0xFE
82#define CE_LOG_BITPOS_SHIFT 1
83
84
85#define ADDR_COL_MASK 0xFFF
86#define ADDR_ROW_MASK 0xFFFF000
87#define ADDR_ROW_SHIFT 12
88#define ADDR_BANK_MASK 0x70000000
89#define ADDR_BANK_SHIFT 28
90
91
92#define STAT_UECNT_MASK 0xFF
93#define STAT_CECNT_MASK 0xFF00
94#define STAT_CECNT_SHIFT 8
95
96
97#define SCRUB_MODE_MASK 0x7
98#define SCRUB_MODE_SECDED 0x4
99
100
101#define DDR_ECC_INTR_SUPPORT BIT(0)
102#define DDR_ECC_DATA_POISON_SUPPORT BIT(1)
103
104
105
106#define ECC_CFG0_OFST 0x70
107#define ECC_CFG1_OFST 0x74
108
109
110#define ECC_STAT_OFST 0x78
111
112
113#define ECC_CLR_OFST 0x7C
114
115
116#define ECC_ERRCNT_OFST 0x80
117
118
119#define ECC_CEADDR0_OFST 0x84
120#define ECC_CEADDR1_OFST 0x88
121
122
123#define ECC_CSYND0_OFST 0x8C
124#define ECC_CSYND1_OFST 0x90
125#define ECC_CSYND2_OFST 0x94
126
127
128#define ECC_BITMASK0_OFST 0x98
129#define ECC_BITMASK1_OFST 0x9C
130#define ECC_BITMASK2_OFST 0xA0
131
132
133#define ECC_UEADDR0_OFST 0xA4
134#define ECC_UEADDR1_OFST 0xA8
135
136
137#define ECC_UESYND0_OFST 0xAC
138#define ECC_UESYND1_OFST 0xB0
139#define ECC_UESYND2_OFST 0xB4
140
141
142#define ECC_POISON0_OFST 0xB8
143#define ECC_POISON1_OFST 0xBC
144
145
146#define ECC_CTRL_BUSWIDTH_MASK 0x3000
147#define ECC_CTRL_BUSWIDTH_SHIFT 12
148#define ECC_CTRL_CLR_CE_ERRCNT BIT(2)
149#define ECC_CTRL_CLR_UE_ERRCNT BIT(3)
150
151
152#define DDRCTL_EWDTH_16 2
153#define DDRCTL_EWDTH_32 1
154#define DDRCTL_EWDTH_64 0
155
156
157#define ECC_STAT_UECNT_MASK 0xF0000
158#define ECC_STAT_UECNT_SHIFT 16
159#define ECC_STAT_CECNT_MASK 0xF00
160#define ECC_STAT_CECNT_SHIFT 8
161#define ECC_STAT_BITNUM_MASK 0x7F
162
163
164#define DDR_QOS_IRQ_STAT_OFST 0x20200
165#define DDR_QOSUE_MASK 0x4
166#define DDR_QOSCE_MASK 0x2
167#define ECC_CE_UE_INTR_MASK 0x6
168#define DDR_QOS_IRQ_EN_OFST 0x20208
169#define DDR_QOS_IRQ_DB_OFST 0x2020C
170
171
172#define ECC_CEADDR0_RW_MASK 0x3FFFF
173#define ECC_CEADDR0_RNK_MASK BIT(24)
174#define ECC_CEADDR1_BNKGRP_MASK 0x3000000
175#define ECC_CEADDR1_BNKNR_MASK 0x70000
176#define ECC_CEADDR1_BLKNR_MASK 0xFFF
177#define ECC_CEADDR1_BNKGRP_SHIFT 24
178#define ECC_CEADDR1_BNKNR_SHIFT 16
179
180
181#define ECC_POISON0_RANK_SHIFT 24
182#define ECC_POISON1_BANKGRP_SHIFT 28
183#define ECC_POISON1_BANKNR_SHIFT 24
184
185
186#define MEM_TYPE_DDR3 0x1
187#define MEM_TYPE_LPDDR3 0x1
188#define MEM_TYPE_DDR2 0x4
189#define MEM_TYPE_DDR4 0x10
190#define MEM_TYPE_LPDDR4 0x10
191
192
193#define DDRC_SWCTL 0x320
194
195
196#define ECC_CEPOISON_MASK 0x3
197#define ECC_UEPOISON_MASK 0x1
198
199
200#define DDRC_MSTR_DEV_CONFIG_MASK 0xC0000000
201#define DDRC_MSTR_DEV_CONFIG_SHIFT 30
202#define DDRC_MSTR_DEV_CONFIG_X4_MASK 0
203#define DDRC_MSTR_DEV_CONFIG_X8_MASK 1
204#define DDRC_MSTR_DEV_CONFIG_X16_MASK 0x10
205#define DDRC_MSTR_DEV_CONFIG_X32_MASK 0X11
206
207
208#define DDR4_COL_SHIFT 3
209#define DDR4_BANKGRP_SHIFT 13
210#define DDR4_BANK_SHIFT 15
211#define DDR4_ROW_SHIFT 17
212#define DDR4_COL_MASK 0x3FF
213#define DDR4_BANKGRP_MASK 0x3
214#define DDR4_BANK_MASK 0x3
215#define DDR4_ROW_MASK 0x7FFF
216
217#define DDR3_COL_SHIFT 3
218#define DDR3_BANK_SHIFT 13
219#define DDR3_ROW_SHIFT 16
220#define DDR3_COL_MASK 0x3FF
221#define DDR3_BANK_MASK 0x7
222#define DDR3_ROW_MASK 0x3FFF
223
224
225
226
227
228
229
230
231
232
233
234struct ecc_error_info {
235 u32 row;
236 u32 col;
237 u32 bank;
238 u32 bitpos;
239 u32 data;
240 u32 bankgrpnr;
241 u32 blknr;
242};
243
244
245
246
247
248
249
250
251struct synps_ecc_status {
252 u32 ce_cnt;
253 u32 ue_cnt;
254 struct ecc_error_info ceinfo;
255 struct ecc_error_info ueinfo;
256};
257
258
259
260
261
262
263
264
265
266
267
268struct synps_edac_priv {
269 void __iomem *baseaddr;
270 char message[SYNPS_EDAC_MSG_SIZE];
271 struct synps_ecc_status stat;
272 const struct synps_platform_data *p_data;
273 u32 ce_cnt;
274 u32 ue_cnt;
275 ulong poison_addr;
276};
277
278
279
280
281
282
283
284
285
286struct synps_platform_data {
287 int (*synps_edac_geterror_info)(void __iomem *base,
288 struct synps_ecc_status *p);
289 enum mem_type (*synps_edac_get_mtype)(const void __iomem *base);
290 enum dev_type (*synps_edac_get_dtype)(const void __iomem *base);
291 bool (*synps_edac_get_eccstate)(void __iomem *base);
292 int quirks;
293};
294
295
296
297
298
299
300
301
302
303
304static int synps_edac_geterror_info(void __iomem *base,
305 struct synps_ecc_status *p)
306{
307 u32 regval, clearval = 0;
308
309 regval = readl(base + STAT_OFST);
310 if (!regval)
311 return 1;
312
313 p->ce_cnt = (regval & STAT_CECNT_MASK) >> STAT_CECNT_SHIFT;
314 p->ue_cnt = regval & STAT_UECNT_MASK;
315
316 regval = readl(base + CE_LOG_OFST);
317 if (!(p->ce_cnt && (regval & LOG_VALID)))
318 goto ue_err;
319
320 p->ceinfo.bitpos = (regval & CE_LOG_BITPOS_MASK) >> CE_LOG_BITPOS_SHIFT;
321 regval = readl(base + CE_ADDR_OFST);
322 p->ceinfo.row = (regval & ADDR_ROW_MASK) >> ADDR_ROW_SHIFT;
323 p->ceinfo.col = regval & ADDR_COL_MASK;
324 p->ceinfo.bank = (regval & ADDR_BANK_MASK) >> ADDR_BANK_SHIFT;
325 p->ceinfo.data = readl(base + CE_DATA_31_0_OFST);
326 edac_dbg(3, "ce bit position: %d data: %d\n", p->ceinfo.bitpos,
327 p->ceinfo.data);
328 clearval = ECC_CTRL_CLR_CE_ERR;
329
330ue_err:
331 regval = readl(base + UE_LOG_OFST);
332 if (!(p->ue_cnt && (regval & LOG_VALID)))
333 goto out;
334
335 regval = readl(base + UE_ADDR_OFST);
336 p->ueinfo.row = (regval & ADDR_ROW_MASK) >> ADDR_ROW_SHIFT;
337 p->ueinfo.col = regval & ADDR_COL_MASK;
338 p->ueinfo.bank = (regval & ADDR_BANK_MASK) >> ADDR_BANK_SHIFT;
339 p->ueinfo.data = readl(base + UE_DATA_31_0_OFST);
340 clearval |= ECC_CTRL_CLR_UE_ERR;
341
342out:
343 writel(clearval, base + ECC_CTRL_OFST);
344 writel(0x0, base + ECC_CTRL_OFST);
345
346 return 0;
347}
348
349
350
351
352
353
354
355
356
357
358static int synps_enh_edac_geterror_info(void __iomem *base,
359 struct synps_ecc_status *p)
360{
361 u32 regval, clearval = 0;
362
363 regval = readl(base + ECC_STAT_OFST);
364 if (!regval)
365 return 1;
366
367 p->ce_cnt = (regval & ECC_STAT_CECNT_MASK) >> ECC_STAT_CECNT_SHIFT;
368 p->ue_cnt = (regval & ECC_STAT_UECNT_MASK) >> ECC_STAT_UECNT_SHIFT;
369 p->ceinfo.bitpos = (regval & ECC_STAT_BITNUM_MASK);
370
371 regval = readl(base + ECC_CEADDR0_OFST);
372 if (!(p->ce_cnt))
373 goto ue_err;
374
375 p->ceinfo.row = (regval & ECC_CEADDR0_RW_MASK);
376 regval = readl(base + ECC_CEADDR1_OFST);
377 p->ceinfo.bank = (regval & ECC_CEADDR1_BNKNR_MASK) >>
378 ECC_CEADDR1_BNKNR_SHIFT;
379 p->ceinfo.bankgrpnr = (regval & ECC_CEADDR1_BNKGRP_MASK) >>
380 ECC_CEADDR1_BNKGRP_SHIFT;
381 p->ceinfo.blknr = (regval & ECC_CEADDR1_BLKNR_MASK);
382 p->ceinfo.data = readl(base + ECC_CSYND0_OFST);
383 edac_dbg(3, "ce bit position: %d data: %d\n", p->ceinfo.bitpos,
384 p->ceinfo.data);
385
386ue_err:
387 regval = readl(base + ECC_UEADDR0_OFST);
388 if (!(p->ue_cnt))
389 goto out;
390
391 p->ueinfo.row = (regval & ECC_CEADDR0_RW_MASK);
392 regval = readl(base + ECC_UEADDR1_OFST);
393 p->ueinfo.bankgrpnr = (regval & ECC_CEADDR1_BNKGRP_MASK) >>
394 ECC_CEADDR1_BNKGRP_SHIFT;
395 p->ueinfo.bank = (regval & ECC_CEADDR1_BNKNR_MASK) >>
396 ECC_CEADDR1_BNKNR_SHIFT;
397 p->ueinfo.blknr = (regval & ECC_CEADDR1_BLKNR_MASK);
398 p->ueinfo.data = readl(base + ECC_UESYND0_OFST);
399out:
400 clearval = ECC_CTRL_CLR_CE_ERR | ECC_CTRL_CLR_CE_ERRCNT;
401 clearval |= ECC_CTRL_CLR_UE_ERR | ECC_CTRL_CLR_UE_ERRCNT;
402 writel(clearval, base + ECC_CLR_OFST);
403 writel(0x0, base + ECC_CLR_OFST);
404
405 return 0;
406}
407
408
409
410
411
412
413
414
415static void synps_edac_handle_error(struct mem_ctl_info *mci,
416 struct synps_ecc_status *p)
417{
418 struct synps_edac_priv *priv = mci->pvt_info;
419 struct ecc_error_info *pinf;
420
421 if (p->ce_cnt) {
422 pinf = &p->ceinfo;
423 if (priv->p_data->quirks == 0)
424 snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
425 "DDR ECC error type :%s Row %d Bank %d Col %d ",
426 "CE", pinf->row, pinf->bank, pinf->col);
427 else
428 snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
429 "DDR ECC error type :%s Row %d Bank %d Col %d "
430 "BankGroup Number %d Block Number %d",
431 "CE", pinf->row, pinf->bank, pinf->col,
432 pinf->bankgrpnr, pinf->blknr);
433
434 edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci,
435 p->ce_cnt, 0, 0, 0, 0, 0, -1,
436 priv->message, "");
437 }
438
439 if (p->ue_cnt) {
440 pinf = &p->ueinfo;
441 if (priv->p_data->quirks == 0)
442 snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
443 "DDR ECC error type :%s Row %d Bank %d Col %d ",
444 "UE", pinf->row, pinf->bank, pinf->col);
445 else
446 snprintf(priv->message, SYNPS_EDAC_MSG_SIZE,
447 "DDR ECC error type :%s Row %d Bank %d Col %d "
448 "BankGroup Number %d Block Number %d",
449 "UE", pinf->row, pinf->bank, pinf->col,
450 pinf->bankgrpnr, pinf->blknr);
451 edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
452 p->ue_cnt, 0, 0, 0, 0, 0, -1,
453 priv->message, "");
454 }
455
456 memset(p, 0, sizeof(*p));
457}
458
459
460
461
462
463
464
465
466
467
468
469static irqreturn_t synps_edac_intr_handler(int irq, void *dev_id)
470{
471 struct mem_ctl_info *mci = dev_id;
472 struct synps_edac_priv *priv = mci->pvt_info;
473 int status, regval;
474
475 regval = readl(priv->baseaddr + DDR_QOS_IRQ_STAT_OFST) &
476 (DDR_QOSCE_MASK | DDR_QOSUE_MASK);
477 if (!(regval & ECC_CE_UE_INTR_MASK))
478 return IRQ_NONE;
479 status = priv->p_data->synps_edac_geterror_info(priv->baseaddr,
480 &priv->stat);
481 if (status)
482 return IRQ_NONE;
483
484 priv->ce_cnt += priv->stat.ce_cnt;
485 priv->ue_cnt += priv->stat.ue_cnt;
486 synps_edac_handle_error(mci, &priv->stat);
487
488 edac_dbg(3, "Total error count ce %d ue %d\n",
489 priv->ce_cnt, priv->ue_cnt);
490 writel(regval, priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
491 return IRQ_HANDLED;
492}
493
494
495
496
497
498
499
500static void synps_edac_check(struct mem_ctl_info *mci)
501{
502 struct synps_edac_priv *priv = mci->pvt_info;
503 int status;
504
505 status = priv->p_data->synps_edac_geterror_info(priv->baseaddr,
506 &priv->stat);
507 if (status)
508 return;
509
510 priv->ce_cnt += priv->stat.ce_cnt;
511 priv->ue_cnt += priv->stat.ue_cnt;
512 synps_edac_handle_error(mci, &priv->stat);
513
514 edac_dbg(3, "Total error count ce %d ue %d\n",
515 priv->ce_cnt, priv->ue_cnt);
516}
517
518
519
520
521
522
523
524
525
526
527static enum dev_type synps_edac_get_dtype(const void __iomem *base)
528{
529 enum dev_type dt;
530 u32 width;
531
532 width = readl(base + CTRL_OFST);
533 width = (width & CTRL_BW_MASK) >> CTRL_BW_SHIFT;
534
535 switch (width) {
536 case DDRCTL_WDTH_16:
537 dt = DEV_X2;
538 break;
539 case DDRCTL_WDTH_32:
540 dt = DEV_X4;
541 break;
542 default:
543 dt = DEV_UNKNOWN;
544 }
545
546 return dt;
547}
548
549
550
551
552
553
554
555
556
557
558static enum dev_type synps_enh_edac_get_dtype(const void __iomem *base)
559{
560 enum dev_type dt;
561 u32 width;
562
563 width = readl(base + CTRL_OFST);
564 width = (width & ECC_CTRL_BUSWIDTH_MASK) >>
565 ECC_CTRL_BUSWIDTH_SHIFT;
566 switch (width) {
567 case DDRCTL_EWDTH_16:
568 dt = DEV_X2;
569 break;
570 case DDRCTL_EWDTH_32:
571 dt = DEV_X4;
572 break;
573 case DDRCTL_EWDTH_64:
574 dt = DEV_X8;
575 break;
576 default:
577 dt = DEV_UNKNOWN;
578 }
579
580 return dt;
581}
582
583
584
585
586
587
588
589
590
591static bool synps_edac_get_eccstate(void __iomem *base)
592{
593 enum dev_type dt;
594 u32 ecctype;
595 bool state = false;
596
597 dt = synps_edac_get_dtype(base);
598 if (dt == DEV_UNKNOWN)
599 return state;
600
601 ecctype = readl(base + SCRUB_OFST) & SCRUB_MODE_MASK;
602 if ((ecctype == SCRUB_MODE_SECDED) && (dt == DEV_X2))
603 state = true;
604
605 return state;
606}
607
608
609
610
611
612
613
614
615
616static bool synps_enh_edac_get_eccstate(void __iomem *base)
617{
618 enum dev_type dt;
619 u32 ecctype;
620 bool state = false;
621
622 dt = synps_enh_edac_get_dtype(base);
623 if (dt == DEV_UNKNOWN)
624 return state;
625
626 ecctype = readl(base + ECC_CFG0_OFST) & SCRUB_MODE_MASK;
627 if ((ecctype == SCRUB_MODE_SECDED) &&
628 ((dt == DEV_X2) || (dt == DEV_X4) || (dt == DEV_X8)))
629 state = true;
630
631 return state;
632}
633
634
635
636
637
638
639static u32 synps_edac_get_memsize(void)
640{
641 struct sysinfo inf;
642
643 si_meminfo(&inf);
644
645 return inf.totalram * inf.mem_unit;
646}
647
648
649
650
651
652
653
654
655
656
657static enum mem_type synps_edac_get_mtype(const void __iomem *base)
658{
659 enum mem_type mt;
660 u32 memtype;
661
662 memtype = readl(base + T_ZQ_OFST);
663
664 if (memtype & T_ZQ_DDRMODE_MASK)
665 mt = MEM_DDR3;
666 else
667 mt = MEM_DDR2;
668
669 return mt;
670}
671
672
673
674
675
676
677
678
679
680
681static enum mem_type synps_enh_edac_get_mtype(const void __iomem *base)
682{
683 enum mem_type mt;
684 u32 memtype;
685
686 memtype = readl(base + CTRL_OFST);
687
688 mt = MEM_UNKNOWN;
689 if ((memtype & MEM_TYPE_DDR3) || (memtype & MEM_TYPE_LPDDR3))
690 mt = MEM_DDR3;
691 else if (memtype & MEM_TYPE_DDR2)
692 mt = MEM_RDDR2;
693 else if ((memtype & MEM_TYPE_LPDDR4) || (memtype & MEM_TYPE_DDR4))
694 mt = MEM_DDR4;
695
696 return mt;
697}
698
699
700
701
702
703
704
705
706
707
708static int synps_edac_init_csrows(struct mem_ctl_info *mci)
709{
710 struct csrow_info *csi;
711 struct dimm_info *dimm;
712 struct synps_edac_priv *priv = mci->pvt_info;
713 u32 size;
714 int row, j;
715
716 for (row = 0; row < mci->nr_csrows; row++) {
717 csi = mci->csrows[row];
718 size = synps_edac_get_memsize();
719
720 for (j = 0; j < csi->nr_channels; j++) {
721 dimm = csi->channels[j]->dimm;
722 dimm->edac_mode = EDAC_FLAG_SECDED;
723 dimm->mtype = priv->p_data->synps_edac_get_mtype(
724 priv->baseaddr);
725 dimm->nr_pages = (size >> PAGE_SHIFT) / csi->nr_channels;
726 dimm->grain = SYNPS_EDAC_ERR_GRAIN;
727 dimm->dtype = priv->p_data->synps_edac_get_dtype(
728 priv->baseaddr);
729 }
730 }
731
732 return 0;
733}
734
735
736
737
738
739
740
741
742
743
744
745
746static int synps_edac_mc_init(struct mem_ctl_info *mci,
747 struct platform_device *pdev)
748{
749 int status;
750 struct synps_edac_priv *priv;
751
752 mci->pdev = &pdev->dev;
753 priv = mci->pvt_info;
754 platform_set_drvdata(pdev, mci);
755
756
757 mci->mtype_cap = MEM_FLAG_DDR3 | MEM_FLAG_DDR2;
758 mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
759 mci->scrub_cap = SCRUB_HW_SRC;
760 mci->scrub_mode = SCRUB_NONE;
761
762 mci->edac_cap = EDAC_FLAG_SECDED;
763 mci->ctl_name = "synps_ddr_controller";
764 mci->dev_name = SYNPS_EDAC_MOD_STRING;
765 mci->mod_name = SYNPS_EDAC_MOD_VER;
766 mci->mod_ver = "1";
767 if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT) {
768 edac_op_state = EDAC_OPSTATE_INT;
769 } else {
770 edac_op_state = EDAC_OPSTATE_POLL;
771 mci->edac_check = synps_edac_check;
772 }
773 mci->ctl_page_to_phys = NULL;
774
775 status = synps_edac_init_csrows(mci);
776
777 return status;
778}
779
780static const struct synps_platform_data zynq_edac_def = {
781 .synps_edac_geterror_info = synps_edac_geterror_info,
782 .synps_edac_get_mtype = synps_edac_get_mtype,
783 .synps_edac_get_dtype = synps_edac_get_dtype,
784 .synps_edac_get_eccstate = synps_edac_get_eccstate,
785 .quirks = 0,
786};
787
788static const struct synps_platform_data zynqmp_enh_edac_def = {
789 .synps_edac_geterror_info = synps_enh_edac_geterror_info,
790 .synps_edac_get_mtype = synps_enh_edac_get_mtype,
791 .synps_edac_get_dtype = synps_enh_edac_get_dtype,
792 .synps_edac_get_eccstate = synps_enh_edac_get_eccstate,
793 .quirks = (DDR_ECC_INTR_SUPPORT |
794 DDR_ECC_DATA_POISON_SUPPORT),
795};
796
797static const struct of_device_id synps_edac_match[] = {
798 { .compatible = "xlnx,zynq-ddrc-a05", .data = (void *)&zynq_edac_def },
799 { .compatible = "xlnx,zynqmp-ddrc-2.40a",
800 .data = (void *)&zynqmp_enh_edac_def},
801 { }
802};
803
804MODULE_DEVICE_TABLE(of, synps_edac_match);
805
806#define to_mci(k) container_of(k, struct mem_ctl_info, dev)
807
808
809
810
811
812
813
814
815
816
817static void ddr4_poison_setup(enum dev_type dttype, int device_config,
818 struct synps_edac_priv *priv)
819{
820 int col, row, bank, bankgrp, regval, shift_val = 0, col_shift;
821
822
823 if (device_config & DDRC_MSTR_DEV_CONFIG_X8_MASK) {
824
825 if (dttype == DEV_X8)
826 shift_val = 0;
827
828 else if (dttype == DEV_X4)
829 shift_val = 1;
830 col_shift = 0;
831 } else if (device_config & DDRC_MSTR_DEV_CONFIG_X16_MASK) {
832 if (dttype == DEV_X8)
833 shift_val = 1;
834 else if (dttype == DEV_X4)
835 shift_val = 2;
836 col_shift = 1;
837 }
838
839 col = (priv->poison_addr >> (DDR4_COL_SHIFT -
840 (shift_val - col_shift))) &
841 DDR4_COL_MASK;
842 row = priv->poison_addr >> (DDR4_ROW_SHIFT - shift_val);
843 row &= DDR4_ROW_MASK;
844 bank = priv->poison_addr >> (DDR4_BANK_SHIFT - shift_val);
845 bank &= DDR4_BANK_MASK;
846 bankgrp = (priv->poison_addr >> (DDR4_BANKGRP_SHIFT -
847 (shift_val - col_shift))) &
848 DDR4_BANKGRP_MASK;
849
850 writel(col, priv->baseaddr + ECC_POISON0_OFST);
851 regval = (bankgrp << ECC_POISON1_BANKGRP_SHIFT) |
852 (bank << ECC_POISON1_BANKNR_SHIFT) | row;
853 writel(regval, priv->baseaddr + ECC_POISON1_OFST);
854}
855
856
857
858
859
860
861
862
863
864
865static void ddr3_poison_setup(enum dev_type dttype, int device_config,
866 struct synps_edac_priv *priv)
867{
868 int col, row, bank, bankgrp, regval, shift_val = 0;
869
870 if (dttype == DEV_X8)
871
872 shift_val = 0;
873 else if (dttype == DEV_X4)
874
875 shift_val = 1;
876
877 col = (priv->poison_addr >> (DDR3_COL_SHIFT - shift_val)) &
878 DDR3_COL_MASK;
879 row = priv->poison_addr >> (DDR3_ROW_SHIFT - shift_val);
880 row &= DDR3_ROW_MASK;
881 bank = priv->poison_addr >> (DDR3_BANK_SHIFT - shift_val);
882 bank &= DDR3_BANK_MASK;
883 bankgrp = 0;
884 writel(col, priv->baseaddr + ECC_POISON0_OFST);
885 regval = (bankgrp << ECC_POISON1_BANKGRP_SHIFT) |
886 (bank << ECC_POISON1_BANKNR_SHIFT) | row;
887 writel(regval, priv->baseaddr + ECC_POISON1_OFST);
888}
889
890
891
892
893
894
895
896
897
898
899static ssize_t synps_edac_mc_inject_data_error_show(struct device *dev,
900 struct device_attribute *mattr,
901 char *data)
902{
903 struct mem_ctl_info *mci = to_mci(dev);
904 struct synps_edac_priv *priv = mci->pvt_info;
905
906 return sprintf(data, "Poison0 Addr: 0x%08x\n\rPoison1 Addr: 0x%08x\n\r"
907 "Error injection Address: 0x%lx\n\r",
908 readl(priv->baseaddr + ECC_POISON0_OFST),
909 readl(priv->baseaddr + ECC_POISON1_OFST),
910 priv->poison_addr);
911}
912
913
914
915
916
917
918
919
920
921
922
923
924static ssize_t synps_edac_mc_inject_data_error_store(struct device *dev,
925 struct device_attribute *mattr,
926 const char *data, size_t count)
927{
928 struct mem_ctl_info *mci = to_mci(dev);
929 struct synps_edac_priv *priv = mci->pvt_info;
930 int device_config;
931 enum mem_type mttype;
932 enum dev_type dttype;
933
934 mttype = priv->p_data->synps_edac_get_mtype(
935 priv->baseaddr);
936 dttype = priv->p_data->synps_edac_get_dtype(
937 priv->baseaddr);
938 if (kstrtoul(data, 0, &priv->poison_addr))
939 return -EINVAL;
940
941 device_config = readl(priv->baseaddr + CTRL_OFST);
942 device_config = (device_config & DDRC_MSTR_DEV_CONFIG_MASK) >>
943 DDRC_MSTR_DEV_CONFIG_SHIFT;
944 if (mttype == MEM_DDR4)
945 ddr4_poison_setup(dttype, device_config, priv);
946 else if (mttype == MEM_DDR3)
947 ddr3_poison_setup(dttype, device_config, priv);
948
949 return count;
950}
951
952
953
954
955
956
957
958
959
960
961static ssize_t synps_edac_mc_inject_data_poison_show(struct device *dev,
962 struct device_attribute *mattr,
963 char *data)
964{
965 struct mem_ctl_info *mci = to_mci(dev);
966 struct synps_edac_priv *priv = mci->pvt_info;
967
968 return sprintf(data, "Data Poisoning: %s\n\r",
969 ((readl(priv->baseaddr + ECC_CFG1_OFST)) & 0x3) ?
970 ("Correctable Error"):("UnCorrectable Error"));
971}
972
973
974
975
976
977
978
979
980
981
982
983static ssize_t synps_edac_mc_inject_data_poison_store(struct device *dev,
984 struct device_attribute *mattr,
985 const char *data, size_t count)
986{
987 struct mem_ctl_info *mci = to_mci(dev);
988 struct synps_edac_priv *priv = mci->pvt_info;
989
990 writel(0, priv->baseaddr + DDRC_SWCTL);
991 if (strncmp(data, "CE", 2) == 0)
992 writel(ECC_CEPOISON_MASK, priv->baseaddr + ECC_CFG1_OFST);
993 else
994 writel(ECC_UEPOISON_MASK, priv->baseaddr + ECC_CFG1_OFST);
995 writel(1, priv->baseaddr + DDRC_SWCTL);
996
997 return count;
998}
999
1000static DEVICE_ATTR(inject_data_error, S_IRUGO | S_IWUSR,
1001 synps_edac_mc_inject_data_error_show,
1002 synps_edac_mc_inject_data_error_store);
1003static DEVICE_ATTR(inject_data_poison, S_IRUGO | S_IWUSR,
1004 synps_edac_mc_inject_data_poison_show,
1005 synps_edac_mc_inject_data_poison_store);
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015static int synps_edac_create_sysfs_attributes(struct mem_ctl_info *mci)
1016{
1017 int rc;
1018
1019 rc = device_create_file(&mci->dev, &dev_attr_inject_data_error);
1020 if (rc < 0)
1021 return rc;
1022 rc = device_create_file(&mci->dev, &dev_attr_inject_data_poison);
1023 if (rc < 0)
1024 return rc;
1025 return 0;
1026}
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036static void synps_edac_remove_sysfs_attributes(struct mem_ctl_info *mci)
1037{
1038 device_remove_file(&mci->dev, &dev_attr_inject_data_error);
1039 device_remove_file(&mci->dev, &dev_attr_inject_data_poison);
1040}
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051static int synps_edac_mc_probe(struct platform_device *pdev)
1052{
1053 struct mem_ctl_info *mci;
1054 struct edac_mc_layer layers[2];
1055 struct synps_edac_priv *priv;
1056 int rc, irq, status;
1057 struct resource *res;
1058 void __iomem *baseaddr;
1059 const struct of_device_id *match;
1060 const struct synps_platform_data *p_data;
1061
1062 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1063 baseaddr = devm_ioremap_resource(&pdev->dev, res);
1064 if (IS_ERR(baseaddr))
1065 return PTR_ERR(baseaddr);
1066
1067 match = of_match_node(synps_edac_match, pdev->dev.of_node);
1068 if (!match && !match->data) {
1069 dev_err(&pdev->dev, "of_match_node() failed\n");
1070 return -EINVAL;
1071 }
1072
1073 p_data = (struct synps_platform_data *)match->data;
1074 if (!(p_data->synps_edac_get_eccstate(baseaddr))) {
1075 edac_printk(KERN_INFO, EDAC_MC, "ECC not enabled\n");
1076 return -ENXIO;
1077 }
1078
1079 layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
1080 layers[0].size = SYNPS_EDAC_NR_CSROWS;
1081 layers[0].is_virt_csrow = true;
1082 layers[1].type = EDAC_MC_LAYER_CHANNEL;
1083 layers[1].size = SYNPS_EDAC_NR_CHANS;
1084 layers[1].is_virt_csrow = false;
1085
1086 mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers,
1087 sizeof(struct synps_edac_priv));
1088 if (!mci) {
1089 edac_printk(KERN_ERR, EDAC_MC,
1090 "Failed memory allocation for mc instance\n");
1091 return -ENOMEM;
1092 }
1093
1094 priv = mci->pvt_info;
1095 priv->baseaddr = baseaddr;
1096 priv->p_data = match->data;
1097
1098 rc = synps_edac_mc_init(mci, pdev);
1099 if (rc) {
1100 edac_printk(KERN_ERR, EDAC_MC,
1101 "Failed to initialize instance\n");
1102 goto free_edac_mc;
1103 }
1104
1105 if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT) {
1106 irq = platform_get_irq(pdev, 0);
1107 if (irq < 0) {
1108 edac_printk(KERN_ERR, EDAC_MC,
1109 "No irq %d in DT\n", irq);
1110 return -ENODEV;
1111 }
1112
1113 status = devm_request_irq(&pdev->dev, irq,
1114 synps_edac_intr_handler,
1115 0, dev_name(&pdev->dev), mci);
1116 if (status < 0) {
1117 edac_printk(KERN_ERR, EDAC_MC, "Failed to request Irq\n");
1118 goto free_edac_mc;
1119 }
1120
1121
1122 writel((DDR_QOSUE_MASK | DDR_QOSCE_MASK),
1123 priv->baseaddr + DDR_QOS_IRQ_EN_OFST);
1124 }
1125
1126 rc = edac_mc_add_mc(mci);
1127 if (rc) {
1128 edac_printk(KERN_ERR, EDAC_MC,
1129 "Failed to register with EDAC core\n");
1130 goto free_edac_mc;
1131 }
1132
1133 if (priv->p_data->quirks & DDR_ECC_DATA_POISON_SUPPORT) {
1134 if (synps_edac_create_sysfs_attributes(mci)) {
1135 edac_printk(KERN_ERR, EDAC_MC,
1136 "Failed to create sysfs entries\n");
1137 goto free_edac_mc;
1138 }
1139 }
1140
1141
1142
1143
1144 if (!(priv->p_data->quirks & DDR_ECC_INTR_SUPPORT))
1145 writel(0x0, baseaddr + ECC_CTRL_OFST);
1146 return rc;
1147
1148free_edac_mc:
1149 edac_mc_free(mci);
1150
1151 return rc;
1152}
1153
1154
1155
1156
1157
1158
1159
1160static int synps_edac_mc_remove(struct platform_device *pdev)
1161{
1162 struct mem_ctl_info *mci = platform_get_drvdata(pdev);
1163 struct synps_edac_priv *priv;
1164
1165 priv = mci->pvt_info;
1166 if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT)
1167
1168 writel((DDR_QOSUE_MASK | DDR_QOSCE_MASK),
1169 priv->baseaddr + DDR_QOS_IRQ_DB_OFST);
1170 edac_mc_del_mc(&pdev->dev);
1171 if (priv->p_data->quirks & DDR_ECC_DATA_POISON_SUPPORT)
1172 synps_edac_remove_sysfs_attributes(mci);
1173 edac_mc_free(mci);
1174
1175 return 0;
1176}
1177
1178static struct platform_driver synps_edac_mc_driver = {
1179 .driver = {
1180 .name = "synopsys-edac",
1181 .of_match_table = synps_edac_match,
1182 },
1183 .probe = synps_edac_mc_probe,
1184 .remove = synps_edac_mc_remove,
1185};
1186
1187module_platform_driver(synps_edac_mc_driver);
1188
1189MODULE_AUTHOR("Xilinx Inc");
1190MODULE_DESCRIPTION("Synopsys DDR ECC driver");
1191MODULE_LICENSE("GPL v2");
1192