aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/cpc925_edac.c
diff options
context:
space:
mode:
authorHarry Ciao <qingtao.cao@windriver.com>2009-06-17 19:27:58 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-18 16:03:56 -0400
commit2a9036afffb3a174e980f90eb507c5aea6b540f6 (patch)
tree6c5d1272aabd9c35ff04760c7280b8e68c328b6a /drivers/edac/cpc925_edac.c
parent26c369dada267d3df1beb86cf89b865ac1178a7f (diff)
edac: add CPC925 Memory Controller driver
Introduce IBM CPC925 EDAC driver, which makes use of ECC, CPU and HyperTransport Link error detections and corrections on the IBM CPC925 Bridge and Memory Controller. [akpm@linux-foundation.org: cleanup] Signed-off-by: Harry Ciao <qingtao.cao@windriver.com> Cc: Doug Thompson <norsk5@yahoo.com> Cc: Michael Ellerman <michael@ellerman.id.au> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Kumar Gala <galak@gate.crashing.org> Cc: Paul Mackerras <paulus@samba.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/edac/cpc925_edac.c')
-rw-r--r--drivers/edac/cpc925_edac.c1017
1 files changed, 1017 insertions, 0 deletions
diff --git a/drivers/edac/cpc925_edac.c b/drivers/edac/cpc925_edac.c
new file mode 100644
index 000000000000..8c54196b5aba
--- /dev/null
+++ b/drivers/edac/cpc925_edac.c
@@ -0,0 +1,1017 @@
1/*
2 * cpc925_edac.c, EDAC driver for IBM CPC925 Bridge and Memory Controller.
3 *
4 * Copyright (c) 2008 Wind River Systems, Inc.
5 *
6 * Authors: Cao Qingtao <qingtao.cao@windriver.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 * See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include <linux/module.h>
23#include <linux/init.h>
24#include <linux/io.h>
25#include <linux/edac.h>
26#include <linux/of.h>
27#include <linux/platform_device.h>
28
29#include "edac_core.h"
30#include "edac_module.h"
31
32#define CPC925_EDAC_REVISION " Ver: 1.0.0 " __DATE__
33#define CPC925_EDAC_MOD_STR "cpc925_edac"
34
35#define cpc925_printk(level, fmt, arg...) \
36 edac_printk(level, "CPC925", fmt, ##arg)
37
38#define cpc925_mc_printk(mci, level, fmt, arg...) \
39 edac_mc_chipset_printk(mci, level, "CPC925", fmt, ##arg)
40
41/*
42 * CPC925 registers are of 32 bits with bit0 defined at the
43 * most significant bit and bit31 at that of least significant.
44 */
45#define CPC925_BITS_PER_REG 32
46#define CPC925_BIT(nr) (1UL << (CPC925_BITS_PER_REG - 1 - nr))
47
48/*
49 * EDAC device names for the error detections of
50 * CPU Interface and Hypertransport Link.
51 */
52#define CPC925_CPU_ERR_DEV "cpu"
53#define CPC925_HT_LINK_DEV "htlink"
54
55/* Suppose DDR Refresh cycle is 15.6 microsecond */
56#define CPC925_REF_FREQ 0xFA69
57#define CPC925_SCRUB_BLOCK_SIZE 64 /* bytes */
58#define CPC925_NR_CSROWS 8
59
60/*
61 * All registers and bits definitions are taken from
62 * "CPC925 Bridge and Memory Controller User Manual, SA14-2761-02".
63 */
64
65/*
66 * CPU and Memory Controller Registers
67 */
68/************************************************************
69 * Processor Interface Exception Mask Register (APIMASK)
70 ************************************************************/
71#define REG_APIMASK_OFFSET 0x30070
72enum apimask_bits {
73 APIMASK_DART = CPC925_BIT(0), /* DART Exception */
74 APIMASK_ADI0 = CPC925_BIT(1), /* Handshake Error on PI0_ADI */
75 APIMASK_ADI1 = CPC925_BIT(2), /* Handshake Error on PI1_ADI */
76 APIMASK_STAT = CPC925_BIT(3), /* Status Exception */
77 APIMASK_DERR = CPC925_BIT(4), /* Data Error Exception */
78 APIMASK_ADRS0 = CPC925_BIT(5), /* Addressing Exception on PI0 */
79 APIMASK_ADRS1 = CPC925_BIT(6), /* Addressing Exception on PI1 */
80 /* BIT(7) Reserved */
81 APIMASK_ECC_UE_H = CPC925_BIT(8), /* UECC upper */
82 APIMASK_ECC_CE_H = CPC925_BIT(9), /* CECC upper */
83 APIMASK_ECC_UE_L = CPC925_BIT(10), /* UECC lower */
84 APIMASK_ECC_CE_L = CPC925_BIT(11), /* CECC lower */
85
86 CPU_MASK_ENABLE = (APIMASK_DART | APIMASK_ADI0 | APIMASK_ADI1 |
87 APIMASK_STAT | APIMASK_DERR | APIMASK_ADRS0 |
88 APIMASK_ADRS1),
89 ECC_MASK_ENABLE = (APIMASK_ECC_UE_H | APIMASK_ECC_CE_H |
90 APIMASK_ECC_UE_L | APIMASK_ECC_CE_L),
91};
92
93/************************************************************
94 * Processor Interface Exception Register (APIEXCP)
95 ************************************************************/
96#define REG_APIEXCP_OFFSET 0x30060
97enum apiexcp_bits {
98 APIEXCP_DART = CPC925_BIT(0), /* DART Exception */
99 APIEXCP_ADI0 = CPC925_BIT(1), /* Handshake Error on PI0_ADI */
100 APIEXCP_ADI1 = CPC925_BIT(2), /* Handshake Error on PI1_ADI */
101 APIEXCP_STAT = CPC925_BIT(3), /* Status Exception */
102 APIEXCP_DERR = CPC925_BIT(4), /* Data Error Exception */
103 APIEXCP_ADRS0 = CPC925_BIT(5), /* Addressing Exception on PI0 */
104 APIEXCP_ADRS1 = CPC925_BIT(6), /* Addressing Exception on PI1 */
105 /* BIT(7) Reserved */
106 APIEXCP_ECC_UE_H = CPC925_BIT(8), /* UECC upper */
107 APIEXCP_ECC_CE_H = CPC925_BIT(9), /* CECC upper */
108 APIEXCP_ECC_UE_L = CPC925_BIT(10), /* UECC lower */
109 APIEXCP_ECC_CE_L = CPC925_BIT(11), /* CECC lower */
110
111 CPU_EXCP_DETECTED = (APIEXCP_DART | APIEXCP_ADI0 | APIEXCP_ADI1 |
112 APIEXCP_STAT | APIEXCP_DERR | APIEXCP_ADRS0 |
113 APIEXCP_ADRS1),
114 UECC_EXCP_DETECTED = (APIEXCP_ECC_UE_H | APIEXCP_ECC_UE_L),
115 CECC_EXCP_DETECTED = (APIEXCP_ECC_CE_H | APIEXCP_ECC_CE_L),
116 ECC_EXCP_DETECTED = (UECC_EXCP_DETECTED | CECC_EXCP_DETECTED),
117};
118
119/************************************************************
120 * Memory Bus Configuration Register (MBCR)
121************************************************************/
122#define REG_MBCR_OFFSET 0x2190
123#define MBCR_64BITCFG_SHIFT 23
124#define MBCR_64BITCFG_MASK (1UL << MBCR_64BITCFG_SHIFT)
125#define MBCR_64BITBUS_SHIFT 22
126#define MBCR_64BITBUS_MASK (1UL << MBCR_64BITBUS_SHIFT)
127
128/************************************************************
129 * Memory Bank Mode Register (MBMR)
130************************************************************/
131#define REG_MBMR_OFFSET 0x21C0
132#define MBMR_MODE_MAX_VALUE 0xF
133#define MBMR_MODE_SHIFT 25
134#define MBMR_MODE_MASK (MBMR_MODE_MAX_VALUE << MBMR_MODE_SHIFT)
135#define MBMR_BBA_SHIFT 24
136#define MBMR_BBA_MASK (1UL << MBMR_BBA_SHIFT)
137
138/************************************************************
139 * Memory Bank Boundary Address Register (MBBAR)
140 ************************************************************/
141#define REG_MBBAR_OFFSET 0x21D0
142#define MBBAR_BBA_MAX_VALUE 0xFF
143#define MBBAR_BBA_SHIFT 24
144#define MBBAR_BBA_MASK (MBBAR_BBA_MAX_VALUE << MBBAR_BBA_SHIFT)
145
146/************************************************************
147 * Memory Scrub Control Register (MSCR)
148 ************************************************************/
149#define REG_MSCR_OFFSET 0x2400
150#define MSCR_SCRUB_MOD_MASK 0xC0000000 /* scrub_mod - bit0:1*/
151#define MSCR_BACKGR_SCRUB 0x40000000 /* 01 */
152#define MSCR_SI_SHIFT 16 /* si - bit8:15*/
153#define MSCR_SI_MAX_VALUE 0xFF
154#define MSCR_SI_MASK (MSCR_SI_MAX_VALUE << MSCR_SI_SHIFT)
155
156/************************************************************
157 * Memory Scrub Range Start Register (MSRSR)
158 ************************************************************/
159#define REG_MSRSR_OFFSET 0x2410
160
161/************************************************************
162 * Memory Scrub Range End Register (MSRER)
163 ************************************************************/
164#define REG_MSRER_OFFSET 0x2420
165
166/************************************************************
167 * Memory Scrub Pattern Register (MSPR)
168 ************************************************************/
169#define REG_MSPR_OFFSET 0x2430
170
171/************************************************************
172 * Memory Check Control Register (MCCR)
173 ************************************************************/
174#define REG_MCCR_OFFSET 0x2440
175enum mccr_bits {
176 MCCR_ECC_EN = CPC925_BIT(0), /* ECC high and low check */
177};
178
179/************************************************************
180 * Memory Check Range End Register (MCRER)
181 ************************************************************/
182#define REG_MCRER_OFFSET 0x2450
183
184/************************************************************
185 * Memory Error Address Register (MEAR)
186 ************************************************************/
187#define REG_MEAR_OFFSET 0x2460
188#define MEAR_BCNT_MAX_VALUE 0x3
189#define MEAR_BCNT_SHIFT 30
190#define MEAR_BCNT_MASK (MEAR_BCNT_MAX_VALUE << MEAR_BCNT_SHIFT)
191#define MEAR_RANK_MAX_VALUE 0x7
192#define MEAR_RANK_SHIFT 27
193#define MEAR_RANK_MASK (MEAR_RANK_MAX_VALUE << MEAR_RANK_SHIFT)
194#define MEAR_COL_MAX_VALUE 0x7FF
195#define MEAR_COL_SHIFT 16
196#define MEAR_COL_MASK (MEAR_COL_MAX_VALUE << MEAR_COL_SHIFT)
197#define MEAR_BANK_MAX_VALUE 0x3
198#define MEAR_BANK_SHIFT 14
199#define MEAR_BANK_MASK (MEAR_BANK_MAX_VALUE << MEAR_BANK_SHIFT)
200#define MEAR_ROW_MASK 0x00003FFF
201
202/************************************************************
203 * Memory Error Syndrome Register (MESR)
204 ************************************************************/
205#define REG_MESR_OFFSET 0x2470
206#define MESR_ECC_SYN_H_MASK 0xFF00
207#define MESR_ECC_SYN_L_MASK 0x00FF
208
209/************************************************************
210 * Memory Mode Control Register (MMCR)
211 ************************************************************/
212#define REG_MMCR_OFFSET 0x2500
213enum mmcr_bits {
214 MMCR_REG_DIMM_MODE = CPC925_BIT(3),
215};
216
217/*
218 * HyperTransport Link Registers
219 */
220/************************************************************
221 * Error Handling/Enumeration Scratch Pad Register (ERRCTRL)
222 ************************************************************/
223#define REG_ERRCTRL_OFFSET 0x70140
224enum errctrl_bits { /* nonfatal interrupts for */
225 ERRCTRL_SERR_NF = CPC925_BIT(0), /* system error */
226 ERRCTRL_CRC_NF = CPC925_BIT(1), /* CRC error */
227 ERRCTRL_RSP_NF = CPC925_BIT(2), /* Response error */
228 ERRCTRL_EOC_NF = CPC925_BIT(3), /* End-Of-Chain error */
229 ERRCTRL_OVF_NF = CPC925_BIT(4), /* Overflow error */
230 ERRCTRL_PROT_NF = CPC925_BIT(5), /* Protocol error */
231
232 ERRCTRL_RSP_ERR = CPC925_BIT(6), /* Response error received */
233 ERRCTRL_CHN_FAL = CPC925_BIT(7), /* Sync flooding detected */
234
235 HT_ERRCTRL_ENABLE = (ERRCTRL_SERR_NF | ERRCTRL_CRC_NF |
236 ERRCTRL_RSP_NF | ERRCTRL_EOC_NF |
237 ERRCTRL_OVF_NF | ERRCTRL_PROT_NF),
238 HT_ERRCTRL_DETECTED = (ERRCTRL_RSP_ERR | ERRCTRL_CHN_FAL),
239};
240
241/************************************************************
242 * Link Configuration and Link Control Register (LINKCTRL)
243 ************************************************************/
244#define REG_LINKCTRL_OFFSET 0x70110
245enum linkctrl_bits {
246 LINKCTRL_CRC_ERR = (CPC925_BIT(22) | CPC925_BIT(23)),
247 LINKCTRL_LINK_FAIL = CPC925_BIT(27),
248
249 HT_LINKCTRL_DETECTED = (LINKCTRL_CRC_ERR | LINKCTRL_LINK_FAIL),
250};
251
252/************************************************************
253 * Link FreqCap/Error/Freq/Revision ID Register (LINKERR)
254 ************************************************************/
255#define REG_LINKERR_OFFSET 0x70120
256enum linkerr_bits {
257 LINKERR_EOC_ERR = CPC925_BIT(17), /* End-Of-Chain error */
258 LINKERR_OVF_ERR = CPC925_BIT(18), /* Receive Buffer Overflow */
259 LINKERR_PROT_ERR = CPC925_BIT(19), /* Protocol error */
260
261 HT_LINKERR_DETECTED = (LINKERR_EOC_ERR | LINKERR_OVF_ERR |
262 LINKERR_PROT_ERR),
263};
264
265/************************************************************
266 * Bridge Control Register (BRGCTRL)
267 ************************************************************/
268#define REG_BRGCTRL_OFFSET 0x70300
269enum brgctrl_bits {
270 BRGCTRL_DETSERR = CPC925_BIT(0), /* SERR on Secondary Bus */
271 BRGCTRL_SECBUSRESET = CPC925_BIT(9), /* Secondary Bus Reset */
272};
273
274/* Private structure for edac memory controller */
275struct cpc925_mc_pdata {
276 void __iomem *vbase;
277 unsigned long total_mem;
278 const char *name;
279 int edac_idx;
280};
281
282/* Private structure for common edac device */
283struct cpc925_dev_info {
284 void __iomem *vbase;
285 struct platform_device *pdev;
286 char *ctl_name;
287 int edac_idx;
288 struct edac_device_ctl_info *edac_dev;
289 void (*init)(struct cpc925_dev_info *dev_info);
290 void (*exit)(struct cpc925_dev_info *dev_info);
291 void (*check)(struct edac_device_ctl_info *edac_dev);
292};
293
294/* Get total memory size from Open Firmware DTB */
295static void get_total_mem(struct cpc925_mc_pdata *pdata)
296{
297 struct device_node *np = NULL;
298 const unsigned int *reg, *reg_end;
299 int len, sw, aw;
300 unsigned long start, size;
301
302 np = of_find_node_by_type(NULL, "memory");
303 if (!np)
304 return;
305
306 aw = of_n_addr_cells(np);
307 sw = of_n_size_cells(np);
308 reg = (const unsigned int *)of_get_property(np, "reg", &len);
309 reg_end = reg + len/4;
310
311 pdata->total_mem = 0;
312 do {
313 start = of_read_number(reg, aw);
314 reg += aw;
315 size = of_read_number(reg, sw);
316 reg += sw;
317 debugf1("%s: start 0x%lx, size 0x%lx\n", __func__,
318 start, size);
319 pdata->total_mem += size;
320 } while (reg < reg_end);
321
322 of_node_put(np);
323 debugf0("%s: total_mem 0x%lx\n", __func__, pdata->total_mem);
324}
325
326static void cpc925_init_csrows(struct mem_ctl_info *mci)
327{
328 struct cpc925_mc_pdata *pdata = mci->pvt_info;
329 struct csrow_info *csrow;
330 int index;
331 u32 mbmr, mbbar, bba;
332 unsigned long row_size, last_nr_pages = 0;
333
334 get_total_mem(pdata);
335
336 for (index = 0; index < mci->nr_csrows; index++) {
337 mbmr = __raw_readl(pdata->vbase + REG_MBMR_OFFSET +
338 0x20 * index);
339 mbbar = __raw_readl(pdata->vbase + REG_MBBAR_OFFSET +
340 0x20 + index);
341 bba = (((mbmr & MBMR_BBA_MASK) >> MBMR_BBA_SHIFT) << 8) |
342 ((mbbar & MBBAR_BBA_MASK) >> MBBAR_BBA_SHIFT);
343
344 if (bba == 0)
345 continue; /* not populated */
346
347 csrow = &mci->csrows[index];
348
349 row_size = bba * (1UL << 28); /* 256M */
350 csrow->first_page = last_nr_pages;
351 csrow->nr_pages = row_size >> PAGE_SHIFT;
352 csrow->last_page = csrow->first_page + csrow->nr_pages - 1;
353 last_nr_pages = csrow->last_page + 1;
354
355 csrow->mtype = MEM_RDDR;
356 csrow->edac_mode = EDAC_SECDED;
357
358 switch (csrow->nr_channels) {
359 case 1: /* Single channel */
360 csrow->grain = 32; /* four-beat burst of 32 bytes */
361 break;
362 case 2: /* Dual channel */
363 default:
364 csrow->grain = 64; /* four-beat burst of 64 bytes */
365 break;
366 }
367
368 switch ((mbmr & MBMR_MODE_MASK) >> MBMR_MODE_SHIFT) {
369 case 6: /* 0110, no way to differentiate X8 VS X16 */
370 case 5: /* 0101 */
371 case 8: /* 1000 */
372 csrow->dtype = DEV_X16;
373 break;
374 case 7: /* 0111 */
375 case 9: /* 1001 */
376 csrow->dtype = DEV_X8;
377 break;
378 default:
379 csrow->dtype = DEV_UNKNOWN;
380 break;
381 }
382 }
383}
384
385/* Enable memory controller ECC detection */
386static void cpc925_mc_init(struct mem_ctl_info *mci)
387{
388 struct cpc925_mc_pdata *pdata = mci->pvt_info;
389 u32 apimask;
390 u32 mccr;
391
392 /* Enable various ECC error exceptions */
393 apimask = __raw_readl(pdata->vbase + REG_APIMASK_OFFSET);
394 if ((apimask & ECC_MASK_ENABLE) == 0) {
395 apimask |= ECC_MASK_ENABLE;
396 __raw_writel(apimask, pdata->vbase + REG_APIMASK_OFFSET);
397 }
398
399 /* Enable ECC detection */
400 mccr = __raw_readl(pdata->vbase + REG_MCCR_OFFSET);
401 if ((mccr & MCCR_ECC_EN) == 0) {
402 mccr |= MCCR_ECC_EN;
403 __raw_writel(mccr, pdata->vbase + REG_MCCR_OFFSET);
404 }
405}
406
407/* Disable memory controller ECC detection */
408static void cpc925_mc_exit(struct mem_ctl_info *mci)
409{
410 /*
411 * WARNING:
412 * We are supposed to clear the ECC error detection bits,
413 * and it will be no problem to do so. However, once they
414 * are cleared here if we want to re-install CPC925 EDAC
415 * module later, setting them up in cpc925_mc_init() will
416 * trigger machine check exception.
417 * Also, it's ok to leave ECC error detection bits enabled,
418 * since they are reset to 1 by default or by boot loader.
419 */
420
421 return;
422}
423
424/*
425 * Revert DDR column/row/bank addresses into page frame number and
426 * offset in page.
427 *
428 * Suppose memory mode is 0x0111(128-bit mode, identical DIMM pairs),
429 * physical address(PA) bits to column address(CA) bits mappings are:
430 * CA 0 1 2 3 4 5 6 7 8 9 10
431 * PA 59 58 57 56 55 54 53 52 51 50 49
432 *
433 * physical address(PA) bits to bank address(BA) bits mappings are:
434 * BA 0 1
435 * PA 43 44
436 *
437 * physical address(PA) bits to row address(RA) bits mappings are:
438 * RA 0 1 2 3 4 5 6 7 8 9 10 11 12
439 * PA 36 35 34 48 47 46 45 40 41 42 39 38 37
440 */
441static void cpc925_mc_get_pfn(struct mem_ctl_info *mci, u32 mear,
442 unsigned long *pfn, unsigned long *offset, int *csrow)
443{
444 u32 bcnt, rank, col, bank, row;
445 u32 c;
446 unsigned long pa;
447 int i;
448
449 bcnt = (mear & MEAR_BCNT_MASK) >> MEAR_BCNT_SHIFT;
450 rank = (mear & MEAR_RANK_MASK) >> MEAR_RANK_SHIFT;
451 col = (mear & MEAR_COL_MASK) >> MEAR_COL_SHIFT;
452 bank = (mear & MEAR_BANK_MASK) >> MEAR_BANK_SHIFT;
453 row = mear & MEAR_ROW_MASK;
454
455 *csrow = rank;
456
457#ifdef CONFIG_EDAC_DEBUG
458 if (mci->csrows[rank].first_page == 0) {
459 cpc925_mc_printk(mci, KERN_ERR, "ECC occurs in a "
460 "non-populated csrow, broken hardware?\n");
461 return;
462 }
463#endif
464
465 /* Revert csrow number */
466 pa = mci->csrows[rank].first_page << PAGE_SHIFT;
467
468 /* Revert column address */
469 col += bcnt;
470 for (i = 0; i < 11; i++) {
471 c = col & 0x1;
472 col >>= 1;
473 pa |= c << (14 - i);
474 }
475
476 /* Revert bank address */
477 pa |= bank << 19;
478
479 /* Revert row address, in 4 steps */
480 for (i = 0; i < 3; i++) {
481 c = row & 0x1;
482 row >>= 1;
483 pa |= c << (26 - i);
484 }
485
486 for (i = 0; i < 3; i++) {
487 c = row & 0x1;
488 row >>= 1;
489 pa |= c << (21 + i);
490 }
491
492 for (i = 0; i < 4; i++) {
493 c = row & 0x1;
494 row >>= 1;
495 pa |= c << (18 - i);
496 }
497
498 for (i = 0; i < 3; i++) {
499 c = row & 0x1;
500 row >>= 1;
501 pa |= c << (29 - i);
502 }
503
504 *offset = pa & (PAGE_SIZE - 1);
505 *pfn = pa >> PAGE_SHIFT;
506
507 debugf0("%s: ECC physical address 0x%lx\n", __func__, pa);
508}
509
510static int cpc925_mc_find_channel(struct mem_ctl_info *mci, u16 syndrome)
511{
512 if ((syndrome & MESR_ECC_SYN_H_MASK) == 0)
513 return 0;
514
515 if ((syndrome & MESR_ECC_SYN_L_MASK) == 0)
516 return 1;
517
518 cpc925_mc_printk(mci, KERN_INFO, "Unexpected syndrome value: 0x%x\n",
519 syndrome);
520 return 1;
521}
522
523/* Check memory controller registers for ECC errors */
524static void cpc925_mc_check(struct mem_ctl_info *mci)
525{
526 struct cpc925_mc_pdata *pdata = mci->pvt_info;
527 u32 apiexcp;
528 u32 mear;
529 u32 mesr;
530 u16 syndrome;
531 unsigned long pfn = 0, offset = 0;
532 int csrow = 0, channel = 0;
533
534 /* APIEXCP is cleared when read */
535 apiexcp = __raw_readl(pdata->vbase + REG_APIEXCP_OFFSET);
536 if ((apiexcp & ECC_EXCP_DETECTED) == 0)
537 return;
538
539 mesr = __raw_readl(pdata->vbase + REG_MESR_OFFSET);
540 syndrome = mesr | (MESR_ECC_SYN_H_MASK | MESR_ECC_SYN_L_MASK);
541
542 mear = __raw_readl(pdata->vbase + REG_MEAR_OFFSET);
543
544 /* Revert column/row addresses into page frame number, etc */
545 cpc925_mc_get_pfn(mci, mear, &pfn, &offset, &csrow);
546
547 if (apiexcp & CECC_EXCP_DETECTED) {
548 cpc925_mc_printk(mci, KERN_INFO, "DRAM CECC Fault\n");
549 channel = cpc925_mc_find_channel(mci, syndrome);
550 edac_mc_handle_ce(mci, pfn, offset, syndrome,
551 csrow, channel, mci->ctl_name);
552 }
553
554 if (apiexcp & UECC_EXCP_DETECTED) {
555 cpc925_mc_printk(mci, KERN_INFO, "DRAM UECC Fault\n");
556 edac_mc_handle_ue(mci, pfn, offset, csrow, mci->ctl_name);
557 }
558
559 cpc925_mc_printk(mci, KERN_INFO, "Dump registers:\n");
560 cpc925_mc_printk(mci, KERN_INFO, "APIMASK 0x%08x\n",
561 __raw_readl(pdata->vbase + REG_APIMASK_OFFSET));
562 cpc925_mc_printk(mci, KERN_INFO, "APIEXCP 0x%08x\n",
563 apiexcp);
564 cpc925_mc_printk(mci, KERN_INFO, "Mem Scrub Ctrl 0x%08x\n",
565 __raw_readl(pdata->vbase + REG_MSCR_OFFSET));
566 cpc925_mc_printk(mci, KERN_INFO, "Mem Scrub Rge Start 0x%08x\n",
567 __raw_readl(pdata->vbase + REG_MSRSR_OFFSET));
568 cpc925_mc_printk(mci, KERN_INFO, "Mem Scrub Rge End 0x%08x\n",
569 __raw_readl(pdata->vbase + REG_MSRER_OFFSET));
570 cpc925_mc_printk(mci, KERN_INFO, "Mem Scrub Pattern 0x%08x\n",
571 __raw_readl(pdata->vbase + REG_MSPR_OFFSET));
572 cpc925_mc_printk(mci, KERN_INFO, "Mem Chk Ctrl 0x%08x\n",
573 __raw_readl(pdata->vbase + REG_MCCR_OFFSET));
574 cpc925_mc_printk(mci, KERN_INFO, "Mem Chk Rge End 0x%08x\n",
575 __raw_readl(pdata->vbase + REG_MCRER_OFFSET));
576 cpc925_mc_printk(mci, KERN_INFO, "Mem Err Address 0x%08x\n",
577 mesr);
578 cpc925_mc_printk(mci, KERN_INFO, "Mem Err Syndrome 0x%08x\n",
579 syndrome);
580}
581
582/******************** CPU err device********************************/
583/* Enable CPU Errors detection */
584static void cpc925_cpu_init(struct cpc925_dev_info *dev_info)
585{
586 u32 apimask;
587
588 apimask = __raw_readl(dev_info->vbase + REG_APIMASK_OFFSET);
589 if ((apimask & CPU_MASK_ENABLE) == 0) {
590 apimask |= CPU_MASK_ENABLE;
591 __raw_writel(apimask, dev_info->vbase + REG_APIMASK_OFFSET);
592 }
593}
594
595/* Disable CPU Errors detection */
596static void cpc925_cpu_exit(struct cpc925_dev_info *dev_info)
597{
598 /*
599 * WARNING:
600 * We are supposed to clear the CPU error detection bits,
601 * and it will be no problem to do so. However, once they
602 * are cleared here if we want to re-install CPC925 EDAC
603 * module later, setting them up in cpc925_cpu_init() will
604 * trigger machine check exception.
605 * Also, it's ok to leave CPU error detection bits enabled,
606 * since they are reset to 1 by default.
607 */
608
609 return;
610}
611
612/* Check for CPU Errors */
613static void cpc925_cpu_check(struct edac_device_ctl_info *edac_dev)
614{
615 struct cpc925_dev_info *dev_info = edac_dev->pvt_info;
616 u32 apiexcp;
617 u32 apimask;
618
619 /* APIEXCP is cleared when read */
620 apiexcp = __raw_readl(dev_info->vbase + REG_APIEXCP_OFFSET);
621 if ((apiexcp & CPU_EXCP_DETECTED) == 0)
622 return;
623
624 apimask = __raw_readl(dev_info->vbase + REG_APIMASK_OFFSET);
625 cpc925_printk(KERN_INFO, "Processor Interface Fault\n"
626 "Processor Interface register dump:\n");
627 cpc925_printk(KERN_INFO, "APIMASK 0x%08x\n", apimask);
628 cpc925_printk(KERN_INFO, "APIEXCP 0x%08x\n", apiexcp);
629
630 edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name);
631}
632
633/******************** HT Link err device****************************/
634/* Enable HyperTransport Link Error detection */
635static void cpc925_htlink_init(struct cpc925_dev_info *dev_info)
636{
637 u32 ht_errctrl;
638
639 ht_errctrl = __raw_readl(dev_info->vbase + REG_ERRCTRL_OFFSET);
640 if ((ht_errctrl & HT_ERRCTRL_ENABLE) == 0) {
641 ht_errctrl |= HT_ERRCTRL_ENABLE;
642 __raw_writel(ht_errctrl, dev_info->vbase + REG_ERRCTRL_OFFSET);
643 }
644}
645
646/* Disable HyperTransport Link Error detection */
647static void cpc925_htlink_exit(struct cpc925_dev_info *dev_info)
648{
649 u32 ht_errctrl;
650
651 ht_errctrl = __raw_readl(dev_info->vbase + REG_ERRCTRL_OFFSET);
652 ht_errctrl &= ~HT_ERRCTRL_ENABLE;
653 __raw_writel(ht_errctrl, dev_info->vbase + REG_ERRCTRL_OFFSET);
654}
655
656/* Check for HyperTransport Link errors */
657static void cpc925_htlink_check(struct edac_device_ctl_info *edac_dev)
658{
659 struct cpc925_dev_info *dev_info = edac_dev->pvt_info;
660 u32 brgctrl = __raw_readl(dev_info->vbase + REG_BRGCTRL_OFFSET);
661 u32 linkctrl = __raw_readl(dev_info->vbase + REG_LINKCTRL_OFFSET);
662 u32 errctrl = __raw_readl(dev_info->vbase + REG_ERRCTRL_OFFSET);
663 u32 linkerr = __raw_readl(dev_info->vbase + REG_LINKERR_OFFSET);
664
665 if (!((brgctrl & BRGCTRL_DETSERR) ||
666 (linkctrl & HT_LINKCTRL_DETECTED) ||
667 (errctrl & HT_ERRCTRL_DETECTED) ||
668 (linkerr & HT_LINKERR_DETECTED)))
669 return;
670
671 cpc925_printk(KERN_INFO, "HT Link Fault\n"
672 "HT register dump:\n");
673 cpc925_printk(KERN_INFO, "Bridge Ctrl 0x%08x\n",
674 brgctrl);
675 cpc925_printk(KERN_INFO, "Link Config Ctrl 0x%08x\n",
676 linkctrl);
677 cpc925_printk(KERN_INFO, "Error Enum and Ctrl 0x%08x\n",
678 errctrl);
679 cpc925_printk(KERN_INFO, "Link Error 0x%08x\n",
680 linkerr);
681
682 /* Clear by write 1 */
683 if (brgctrl & BRGCTRL_DETSERR)
684 __raw_writel(BRGCTRL_DETSERR,
685 dev_info->vbase + REG_BRGCTRL_OFFSET);
686
687 if (linkctrl & HT_LINKCTRL_DETECTED)
688 __raw_writel(HT_LINKCTRL_DETECTED,
689 dev_info->vbase + REG_LINKCTRL_OFFSET);
690
691 /* Initiate Secondary Bus Reset to clear the chain failure */
692 if (errctrl & ERRCTRL_CHN_FAL)
693 __raw_writel(BRGCTRL_SECBUSRESET,
694 dev_info->vbase + REG_BRGCTRL_OFFSET);
695
696 if (errctrl & ERRCTRL_RSP_ERR)
697 __raw_writel(ERRCTRL_RSP_ERR,
698 dev_info->vbase + REG_ERRCTRL_OFFSET);
699
700 if (linkerr & HT_LINKERR_DETECTED)
701 __raw_writel(HT_LINKERR_DETECTED,
702 dev_info->vbase + REG_LINKERR_OFFSET);
703
704 edac_device_handle_ce(edac_dev, 0, 0, edac_dev->ctl_name);
705}
706
707static struct cpc925_dev_info cpc925_devs[] = {
708 {
709 .ctl_name = CPC925_CPU_ERR_DEV,
710 .init = cpc925_cpu_init,
711 .exit = cpc925_cpu_exit,
712 .check = cpc925_cpu_check,
713 },
714 {
715 .ctl_name = CPC925_HT_LINK_DEV,
716 .init = cpc925_htlink_init,
717 .exit = cpc925_htlink_exit,
718 .check = cpc925_htlink_check,
719 },
720 {0}, /* Terminated by NULL */
721};
722
723/*
724 * Add CPU Err detection and HyperTransport Link Err detection
725 * as common "edac_device", they have no corresponding device
726 * nodes in the Open Firmware DTB and we have to add platform
727 * devices for them. Also, they will share the MMIO with that
728 * of memory controller.
729 */
730static void cpc925_add_edac_devices(void __iomem *vbase)
731{
732 struct cpc925_dev_info *dev_info;
733
734 if (!vbase) {
735 cpc925_printk(KERN_ERR, "MMIO not established yet\n");
736 return;
737 }
738
739 for (dev_info = &cpc925_devs[0]; dev_info->init; dev_info++) {
740 dev_info->vbase = vbase;
741 dev_info->pdev = platform_device_register_simple(
742 dev_info->ctl_name, 0, NULL, 0);
743 if (IS_ERR(dev_info->pdev)) {
744 cpc925_printk(KERN_ERR,
745 "Can't register platform device for %s\n",
746 dev_info->ctl_name);
747 continue;
748 }
749
750 /*
751 * Don't have to allocate private structure but
752 * make use of cpc925_devs[] instead.
753 */
754 dev_info->edac_idx = edac_device_alloc_index();
755 dev_info->edac_dev =
756 edac_device_alloc_ctl_info(0, dev_info->ctl_name,
757 1, NULL, 0, 0, NULL, 0, dev_info->edac_idx);
758 if (!dev_info->edac_dev) {
759 cpc925_printk(KERN_ERR, "No memory for edac device\n");
760 goto err1;
761 }
762
763 dev_info->edac_dev->pvt_info = dev_info;
764 dev_info->edac_dev->dev = &dev_info->pdev->dev;
765 dev_info->edac_dev->ctl_name = dev_info->ctl_name;
766 dev_info->edac_dev->mod_name = CPC925_EDAC_MOD_STR;
767 dev_info->edac_dev->dev_name = dev_name(&dev_info->pdev->dev);
768
769 if (edac_op_state == EDAC_OPSTATE_POLL)
770 dev_info->edac_dev->edac_check = dev_info->check;
771
772 if (dev_info->init)
773 dev_info->init(dev_info);
774
775 if (edac_device_add_device(dev_info->edac_dev) > 0) {
776 cpc925_printk(KERN_ERR,
777 "Unable to add edac device for %s\n",
778 dev_info->ctl_name);
779 goto err2;
780 }
781
782 debugf0("%s: Successfully added edac device for %s\n",
783 __func__, dev_info->ctl_name);
784
785 continue;
786
787err2:
788 if (dev_info->exit)
789 dev_info->exit(dev_info);
790 edac_device_free_ctl_info(dev_info->edac_dev);
791err1:
792 platform_device_unregister(dev_info->pdev);
793 }
794}
795
796/*
797 * Delete the common "edac_device" for CPU Err Detection
798 * and HyperTransport Link Err Detection
799 */
800static void cpc925_del_edac_devices(void)
801{
802 struct cpc925_dev_info *dev_info;
803
804 for (dev_info = &cpc925_devs[0]; dev_info->init; dev_info++) {
805 if (dev_info->edac_dev) {
806 edac_device_del_device(dev_info->edac_dev->dev);
807 edac_device_free_ctl_info(dev_info->edac_dev);
808 platform_device_unregister(dev_info->pdev);
809 }
810
811 if (dev_info->exit)
812 dev_info->exit(dev_info);
813
814 debugf0("%s: Successfully deleted edac device for %s\n",
815 __func__, dev_info->ctl_name);
816 }
817}
818
819/* Convert current back-ground scrub rate into byte/sec bandwith */
820static int cpc925_get_sdram_scrub_rate(struct mem_ctl_info *mci, u32 *bw)
821{
822 struct cpc925_mc_pdata *pdata = mci->pvt_info;
823 u32 mscr;
824 u8 si;
825
826 mscr = __raw_readl(pdata->vbase + REG_MSCR_OFFSET);
827 si = (mscr & MSCR_SI_MASK) >> MSCR_SI_SHIFT;
828
829 debugf0("%s, Mem Scrub Ctrl Register 0x%x\n", __func__, mscr);
830
831 if (((mscr & MSCR_SCRUB_MOD_MASK) != MSCR_BACKGR_SCRUB) ||
832 (si == 0)) {
833 cpc925_mc_printk(mci, KERN_INFO, "Scrub mode not enabled\n");
834 *bw = 0;
835 } else
836 *bw = CPC925_SCRUB_BLOCK_SIZE * 0xFA67 / si;
837
838 return 0;
839}
840
841/* Return 0 for single channel; 1 for dual channel */
842static int cpc925_mc_get_channels(void __iomem *vbase)
843{
844 int dual = 0;
845 u32 mbcr;
846
847 mbcr = __raw_readl(vbase + REG_MBCR_OFFSET);
848
849 /*
850 * Dual channel only when 128-bit wide physical bus
851 * and 128-bit configuration.
852 */
853 if (((mbcr & MBCR_64BITCFG_MASK) == 0) &&
854 ((mbcr & MBCR_64BITBUS_MASK) == 0))
855 dual = 1;
856
857 debugf0("%s: %s channel\n", __func__,
858 (dual > 0) ? "Dual" : "Single");
859
860 return dual;
861}
862
863static int __devinit cpc925_probe(struct platform_device *pdev)
864{
865 static int edac_mc_idx;
866 struct mem_ctl_info *mci;
867 void __iomem *vbase;
868 struct cpc925_mc_pdata *pdata;
869 struct resource *r;
870 int res = 0, nr_channels;
871
872 debugf0("%s: %s platform device found!\n", __func__, pdev->name);
873
874 if (!devres_open_group(&pdev->dev, cpc925_probe, GFP_KERNEL)) {
875 res = -ENOMEM;
876 goto out;
877 }
878
879 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
880 if (!r) {
881 cpc925_printk(KERN_ERR, "Unable to get resource\n");
882 res = -ENOENT;
883 goto err1;
884 }
885
886 if (!devm_request_mem_region(&pdev->dev,
887 r->start,
888 r->end - r->start + 1,
889 pdev->name)) {
890 cpc925_printk(KERN_ERR, "Unable to request mem region\n");
891 res = -EBUSY;
892 goto err1;
893 }
894
895 vbase = devm_ioremap(&pdev->dev, r->start, r->end - r->start + 1);
896 if (!vbase) {
897 cpc925_printk(KERN_ERR, "Unable to ioremap device\n");
898 res = -ENOMEM;
899 goto err2;
900 }
901
902 nr_channels = cpc925_mc_get_channels(vbase);
903 mci = edac_mc_alloc(sizeof(struct cpc925_mc_pdata),
904 CPC925_NR_CSROWS, nr_channels + 1, edac_mc_idx);
905 if (!mci) {
906 cpc925_printk(KERN_ERR, "No memory for mem_ctl_info\n");
907 res = -ENOMEM;
908 goto err2;
909 }
910
911 pdata = mci->pvt_info;
912 pdata->vbase = vbase;
913 pdata->edac_idx = edac_mc_idx++;
914 pdata->name = pdev->name;
915
916 mci->dev = &pdev->dev;
917 platform_set_drvdata(pdev, mci);
918 mci->dev_name = dev_name(&pdev->dev);
919 mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_DDR;
920 mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
921 mci->edac_cap = EDAC_FLAG_SECDED;
922 mci->mod_name = CPC925_EDAC_MOD_STR;
923 mci->mod_ver = CPC925_EDAC_REVISION;
924 mci->ctl_name = pdev->name;
925
926 if (edac_op_state == EDAC_OPSTATE_POLL)
927 mci->edac_check = cpc925_mc_check;
928
929 mci->ctl_page_to_phys = NULL;
930 mci->scrub_mode = SCRUB_SW_SRC;
931 mci->set_sdram_scrub_rate = NULL;
932 mci->get_sdram_scrub_rate = cpc925_get_sdram_scrub_rate;
933
934 cpc925_init_csrows(mci);
935
936 /* Setup memory controller registers */
937 cpc925_mc_init(mci);
938
939 if (edac_mc_add_mc(mci) > 0) {
940 cpc925_mc_printk(mci, KERN_ERR, "Failed edac_mc_add_mc()\n");
941 goto err3;
942 }
943
944 cpc925_add_edac_devices(vbase);
945
946 /* get this far and it's successful */
947 debugf0("%s: success\n", __func__);
948
949 res = 0;
950 goto out;
951
952err3:
953 cpc925_mc_exit(mci);
954 edac_mc_free(mci);
955err2:
956 devm_release_mem_region(&pdev->dev, r->start, r->end-r->start+1);
957err1:
958 devres_release_group(&pdev->dev, cpc925_probe);
959out:
960 return res;
961}
962
963static int cpc925_remove(struct platform_device *pdev)
964{
965 struct mem_ctl_info *mci = platform_get_drvdata(pdev);
966
967 /*
968 * Delete common edac devices before edac mc, because
969 * the former share the MMIO of the latter.
970 */
971 cpc925_del_edac_devices();
972 cpc925_mc_exit(mci);
973
974 edac_mc_del_mc(&pdev->dev);
975 edac_mc_free(mci);
976
977 return 0;
978}
979
980static struct platform_driver cpc925_edac_driver = {
981 .probe = cpc925_probe,
982 .remove = cpc925_remove,
983 .driver = {
984 .name = "cpc925_edac",
985 }
986};
987
988static int __init cpc925_edac_init(void)
989{
990 int ret = 0;
991
992 printk(KERN_INFO "IBM CPC925 EDAC driver " CPC925_EDAC_REVISION "\n");
993 printk(KERN_INFO "\t(c) 2008 Wind River Systems, Inc\n");
994
995 /* Only support POLL mode so far */
996 edac_op_state = EDAC_OPSTATE_POLL;
997
998 ret = platform_driver_register(&cpc925_edac_driver);
999 if (ret) {
1000 printk(KERN_WARNING "Failed to register %s\n",
1001 CPC925_EDAC_MOD_STR);
1002 }
1003
1004 return ret;
1005}
1006
1007static void __exit cpc925_edac_exit(void)
1008{
1009 platform_driver_unregister(&cpc925_edac_driver);
1010}
1011
1012module_init(cpc925_edac_init);
1013module_exit(cpc925_edac_exit);
1014
1015MODULE_LICENSE("GPL");
1016MODULE_AUTHOR("Cao Qingtao <qingtao.cao@windriver.com>");
1017MODULE_DESCRIPTION("IBM CPC925 Bridge and MC EDAC kernel module");