1806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox/*
2806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox * Intel e752x Memory Controller kernel module
3806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox * (C) 2004 Linux Networx (http://lnxi.com)
4806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox * This file may be distributed under the terms of the
5806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox * GNU General Public License.
6806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox *
7806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox * See "enum e752x_chips" below for supported chipsets
8806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox *
9806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox * Written by Tom Zimmerman
10806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox *
11806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox * Contributors:
12806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox * 	Thayne Harbaugh at realmsys.com (?)
13806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox * 	Wang Zhenyu at intel.com
14806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox * 	Dave Jiang at mvista.com
15806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox *
16da9bb1d27b21cb24cbb6a2efb5d3c464d357a01eAlan Cox * $Id: edac_e752x.c,v 1.5.2.11 2005/10/05 00:43:44 dsp_llnl Exp $
17806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox *
18806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox */
19806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
20806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#include <linux/module.h>
21806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#include <linux/init.h>
22806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#include <linux/pci.h>
23806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#include <linux/pci_ids.h>
24c0d121720220584bba2876b032e58a076b843fa1Dave Jiang#include <linux/edac.h>
2520bcb7a81dee21bfa3408f03f46b2891c9b5c84bDouglas Thompson#include "edac_core.h"
26806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
27152ba3942276c2a240703669ae4a3099e0a79451Michal Marek#define E752X_REVISION	" Ver: 2.0.2"
28929a40ec324e947d4ad14cc1ced785c104c560e2Doug Thompson#define EDAC_MOD_STR	"e752x_edac"
2937f04581abac20444e5b7106c1e1f28bec5b989cDoug Thompson
3010d33e9c36827e5371479e55ef4089e000af2638Doug Thompsonstatic int report_non_memory_errors;
3196941026a51e9cb8c2d2be7499301b7fcd9ee225mark grossstatic int force_function_unhide;
3294ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyserstatic int sysbus_parity = -1;
3396941026a51e9cb8c2d2be7499301b7fcd9ee225mark gross
3491b99041c1d577ded1da599ddc28cec2e07253cfDave Jiangstatic struct edac_pci_ctl_info *e752x_pci;
3591b99041c1d577ded1da599ddc28cec2e07253cfDave Jiang
36537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson#define e752x_printk(level, fmt, arg...) \
37e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson	edac_printk(level, "e752x", fmt, ##arg)
38537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson
39537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson#define e752x_mc_printk(mci, level, fmt, arg...) \
40e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson	edac_mc_chipset_printk(mci, level, "e752x", fmt, ##arg)
41537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson
42806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#ifndef PCI_DEVICE_ID_INTEL_7520_0
43806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define PCI_DEVICE_ID_INTEL_7520_0      0x3590
44806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#endif				/* PCI_DEVICE_ID_INTEL_7520_0      */
45806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
46806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#ifndef PCI_DEVICE_ID_INTEL_7520_1_ERR
47806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define PCI_DEVICE_ID_INTEL_7520_1_ERR  0x3591
48806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#endif				/* PCI_DEVICE_ID_INTEL_7520_1_ERR  */
49806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
50806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#ifndef PCI_DEVICE_ID_INTEL_7525_0
51806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define PCI_DEVICE_ID_INTEL_7525_0      0x359E
52806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#endif				/* PCI_DEVICE_ID_INTEL_7525_0      */
53806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
54806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#ifndef PCI_DEVICE_ID_INTEL_7525_1_ERR
55806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define PCI_DEVICE_ID_INTEL_7525_1_ERR  0x3593
56806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#endif				/* PCI_DEVICE_ID_INTEL_7525_1_ERR  */
57806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
58806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#ifndef PCI_DEVICE_ID_INTEL_7320_0
59806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define PCI_DEVICE_ID_INTEL_7320_0	0x3592
60806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#endif				/* PCI_DEVICE_ID_INTEL_7320_0 */
61806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
62806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#ifndef PCI_DEVICE_ID_INTEL_7320_1_ERR
63806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define PCI_DEVICE_ID_INTEL_7320_1_ERR	0x3593
64806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#endif				/* PCI_DEVICE_ID_INTEL_7320_1_ERR */
65806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
665135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov#ifndef PCI_DEVICE_ID_INTEL_3100_0
675135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov#define PCI_DEVICE_ID_INTEL_3100_0	0x35B0
685135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov#endif				/* PCI_DEVICE_ID_INTEL_3100_0 */
695135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov
705135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov#ifndef PCI_DEVICE_ID_INTEL_3100_1_ERR
715135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov#define PCI_DEVICE_ID_INTEL_3100_1_ERR	0x35B1
725135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov#endif				/* PCI_DEVICE_ID_INTEL_3100_1_ERR */
735135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov
74806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_NR_CSROWS		8	/* number of csrows */
75806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
76806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox/* E752X register addresses - device 0 function 0 */
778004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser#define E752X_MCHSCRB		0x52	/* Memory Scrub register (16b) */
788004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser					/*
798004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser					 * 6:5     Scrub Completion Count
808004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser					 * 3:2     Scrub Rate (i3100 only)
818004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser					 *      01=fast 10=normal
828004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser					 * 1:0     Scrub Mode enable
838004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser					 *      00=off 10=on
848004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser					 */
85806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_DRB		0x60	/* DRAM row boundary register (8b) */
86806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_DRA		0x70	/* DRAM row attribute register (8b) */
87806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					/*
88806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 * 31:30   Device width row 7
89806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 *      01=x8 10=x4 11=x8 DDR2
90806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 * 27:26   Device width row 6
91806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 * 23:22   Device width row 5
92806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 * 19:20   Device width row 4
93806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 * 15:14   Device width row 3
94806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 * 11:10   Device width row 2
95806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 *  7:6    Device width row 1
96806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 *  3:2    Device width row 0
97806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 */
98806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_DRC		0x7C	/* DRAM controller mode reg (32b) */
99806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					/* FIXME:IS THIS RIGHT? */
100806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					/*
101806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 * 22    Number channels 0=1,1=2
102806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 * 19:18 DRB Granularity 32/64MB
103806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 */
104806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_DRM		0x80	/* Dimm mapping register */
105806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_DDRCSR		0x9A	/* DDR control and status reg (16b) */
106806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					/*
107806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 * 14:12 1 single A, 2 single B, 3 dual
108806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 */
109806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_TOLM		0xC4	/* DRAM top of low memory reg (16b) */
110806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_REMAPBASE		0xC6	/* DRAM remap base address reg (16b) */
111806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_REMAPLIMIT	0xC8	/* DRAM remap limit address reg (16b) */
112806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_REMAPOFFSET	0xCA	/* DRAM remap limit offset reg (16b) */
113806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
114806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox/* E752X register addresses - device 0 function 1 */
115806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_FERR_GLOBAL	0x40	/* Global first error register (32b) */
116806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_NERR_GLOBAL	0x44	/* Global next error register (32b) */
117806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_HI_FERR		0x50	/* Hub interface first error reg (8b) */
118806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_HI_NERR		0x52	/* Hub interface next error reg (8b) */
119806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_HI_ERRMASK	0x54	/* Hub interface error mask reg (8b) */
120806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_HI_SMICMD		0x5A	/* Hub interface SMI command reg (8b) */
121806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_SYSBUS_FERR	0x60	/* System buss first error reg (16b) */
122806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_SYSBUS_NERR	0x62	/* System buss next error reg (16b) */
123806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_SYSBUS_ERRMASK	0x64	/* System buss error mask reg (16b) */
124806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_SYSBUS_SMICMD	0x6A	/* System buss SMI command reg (16b) */
125806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_BUF_FERR		0x70	/* Memory buffer first error reg (8b) */
126806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_BUF_NERR		0x72	/* Memory buffer next error reg (8b) */
127806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_BUF_ERRMASK	0x74	/* Memory buffer error mask reg (8b) */
12810d33e9c36827e5371479e55ef4089e000af2638Doug Thompson#define E752X_BUF_SMICMD	0x7A	/* Memory buffer SMI cmd reg (8b) */
129806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_DRAM_FERR		0x80	/* DRAM first error register (16b) */
130806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_DRAM_NERR		0x82	/* DRAM next error register (16b) */
131806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_DRAM_ERRMASK	0x84	/* DRAM error mask register (8b) */
132806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_DRAM_SMICMD	0x8A	/* DRAM SMI command register (8b) */
133806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_DRAM_RETR_ADD	0xAC	/* DRAM Retry address register (32b) */
134806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_DRAM_SEC1_ADD	0xA0	/* DRAM first correctable memory */
135806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					/*     error address register (32b) */
136806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					/*
137806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 * 31    Reserved
13810d33e9c36827e5371479e55ef4089e000af2638Doug Thompson					 * 30:2  CE address (64 byte block 34:6
139806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 * 1     Reserved
140806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 * 0     HiLoCS
141806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 */
142806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_DRAM_SEC2_ADD	0xC8	/* DRAM first correctable memory */
143806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					/*     error address register (32b) */
144806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					/*
145806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 * 31    Reserved
146806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 * 30:2  CE address (64 byte block 34:6)
147806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 * 1     Reserved
148806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 * 0     HiLoCS
149806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 */
150806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_DRAM_DED_ADD	0xA4	/* DRAM first uncorrectable memory */
151806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					/*     error address register (32b) */
152806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					/*
153806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 * 31    Reserved
154806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 * 30:2  CE address (64 byte block 34:6)
155806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 * 1     Reserved
156806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 * 0     HiLoCS
157806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 */
15810d33e9c36827e5371479e55ef4089e000af2638Doug Thompson#define E752X_DRAM_SCRB_ADD	0xA8	/* DRAM 1st uncorrectable scrub mem */
159806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					/*     error address register (32b) */
160806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					/*
161806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 * 31    Reserved
16210d33e9c36827e5371479e55ef4089e000af2638Doug Thompson					 * 30:2  CE address (64 byte block 34:6
163806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 * 1     Reserved
164806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 * 0     HiLoCS
165806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					 */
166806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_DRAM_SEC1_SYNDROME 0xC4	/* DRAM first correctable memory */
167806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					/*     error syndrome register (16b) */
168806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_DRAM_SEC2_SYNDROME 0xC6	/* DRAM second correctable memory */
169806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox					/*     error syndrome register (16b) */
170806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define E752X_DEVPRES1		0xF4	/* Device Present 1 register (8b) */
171806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
1725135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov/* 3100 IMCH specific register addresses - device 0 function 1 */
1735135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov#define I3100_NSI_FERR		0x48	/* NSI first error reg (32b) */
1745135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov#define I3100_NSI_NERR		0x4C	/* NSI next error reg (32b) */
1755135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov#define I3100_NSI_SMICMD	0x54	/* NSI SMI command register (32b) */
1765135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov#define I3100_NSI_EMASK		0x90	/* NSI error mask register (32b) */
1775135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov
178806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox/* ICH5R register addresses - device 30 function 0 */
179806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define ICH5R_PCI_STAT		0x06	/* PCI status register (16b) */
180806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define ICH5R_PCI_2ND_STAT	0x1E	/* PCI status secondary reg (16b) */
181806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox#define ICH5R_PCI_BRIDGE_CTL	0x3E	/* PCI bridge control register (16b) */
182806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
183806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxenum e752x_chips {
184806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	E7520 = 0,
185806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	E7525 = 1,
1865135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	E7320 = 2,
1875135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	I3100 = 3
188806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox};
189806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
190806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstruct e752x_pvt {
191806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	struct pci_dev *bridge_ck;
192806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	struct pci_dev *dev_d0f0;
193806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	struct pci_dev *dev_d0f1;
194806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u32 tolm;
195806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u32 remapbase;
196806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u32 remaplimit;
197806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	int mc_symmetric;
198806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u8 map[8];
199806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	int map_type;
200806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	const struct e752x_dev_info *dev_info;
201806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox};
202806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
203806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstruct e752x_dev_info {
204806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u16 err_dev;
2053847bccce80c8a01d7adbad9961564252207302aDave Peterson	u16 ctl_dev;
206806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	const char *ctl_name;
207806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox};
208806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
209806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstruct e752x_error_info {
210806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u32 ferr_global;
211806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u32 nerr_global;
2125135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	u32 nsi_ferr;	/* 3100 only */
2135135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	u32 nsi_nerr;	/* 3100 only */
2145135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	u8 hi_ferr;	/* all but 3100 */
2155135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	u8 hi_nerr;	/* all but 3100 */
216806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u16 sysbus_ferr;
217806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u16 sysbus_nerr;
218806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u8 buf_ferr;
219806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u8 buf_nerr;
220806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u16 dram_ferr;
221806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u16 dram_nerr;
222806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u32 dram_sec1_add;
223806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u32 dram_sec2_add;
224806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u16 dram_sec1_syndrome;
225806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u16 dram_sec2_syndrome;
226806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u32 dram_ded_add;
227806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u32 dram_scrb_add;
228806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u32 dram_retr_add;
229806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox};
230806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
231806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstatic const struct e752x_dev_info e752x_devs[] = {
232806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	[E7520] = {
233052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson		.err_dev = PCI_DEVICE_ID_INTEL_7520_1_ERR,
234052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson		.ctl_dev = PCI_DEVICE_ID_INTEL_7520_0,
235052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson		.ctl_name = "E7520"},
236806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	[E7525] = {
237052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson		.err_dev = PCI_DEVICE_ID_INTEL_7525_1_ERR,
238052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson		.ctl_dev = PCI_DEVICE_ID_INTEL_7525_0,
239052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson		.ctl_name = "E7525"},
240806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	[E7320] = {
241052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson		.err_dev = PCI_DEVICE_ID_INTEL_7320_1_ERR,
242052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson		.ctl_dev = PCI_DEVICE_ID_INTEL_7320_0,
243052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson		.ctl_name = "E7320"},
2445135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	[I3100] = {
2455135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		.err_dev = PCI_DEVICE_ID_INTEL_3100_1_ERR,
2465135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		.ctl_dev = PCI_DEVICE_ID_INTEL_3100_0,
2475135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		.ctl_name = "3100"},
248806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox};
249806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
2508004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser/* Valid scrub rates for the e752x/3100 hardware memory scrubber. We
2518004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser * map the scrubbing bandwidth to a hardware register value. The 'set'
2528004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser * operation finds the 'matching or higher value'.  Note that scrubbing
2538004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser * on the e752x can only be enabled/disabled.  The 3100 supports
2548004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser * a normal and fast mode.
2558004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser */
2568004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser
2578004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser#define SDRATE_EOT 0xFFFFFFFF
2588004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser
2598004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyserstruct scrubrate {
2608004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	u32 bandwidth;	/* bandwidth consumed by scrubbing in bytes/sec */
2618004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	u16 scrubval;	/* register value for scrub rate */
2628004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser};
2638004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser
2648004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser/* Rate below assumes same performance as i3100 using PC3200 DDR2 in
2658004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser * normal mode.  e752x bridges don't support choosing normal or fast mode,
2668004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser * so the scrubbing bandwidth value isn't all that important - scrubbing is
2678004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser * either on or off.
2688004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser */
2698004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyserstatic const struct scrubrate scrubrates_e752x[] = {
2708004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	{0,		0x00},	/* Scrubbing Off */
2718004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	{500000,	0x02},	/* Scrubbing On */
2728004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	{SDRATE_EOT,	0x00}	/* End of Table */
2738004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser};
2748004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser
2758004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser/* Fast mode: 2 GByte PC3200 DDR2 scrubbed in 33s = 63161283 bytes/s
2768004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser * Normal mode: 125 (32000 / 256) times slower than fast mode.
2778004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser */
2788004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyserstatic const struct scrubrate scrubrates_i3100[] = {
2798004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	{0,		0x00},	/* Scrubbing Off */
2808004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	{500000,	0x0a},	/* Normal mode - 32k clocks */
2818004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	{62500000,	0x06},	/* Fast mode - 256 clocks */
2828004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	{SDRATE_EOT,	0x00}	/* End of Table */
2838004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser};
2848004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser
285806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstatic unsigned long ctl_page_to_phys(struct mem_ctl_info *mci,
286052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				unsigned long page)
287806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
288806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u32 remap;
289203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	struct e752x_pvt *pvt = (struct e752x_pvt *)mci->pvt_info;
290806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
291537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson	debugf3("%s()\n", __func__);
292806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
293806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	if (page < pvt->tolm)
294806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		return page;
295e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
296806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	if ((page >= 0x100000) && (page < pvt->remapbase))
297806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		return page;
298e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
299806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	remap = (page - pvt->tolm) + pvt->remapbase;
300e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
301806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	if (remap < pvt->remaplimit)
302806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		return remap;
303e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
304537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson	e752x_printk(KERN_ERR, "Invalid page %lx - out of range\n", page);
305806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	return pvt->tolm - 1;
306806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
307806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
308806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstatic void do_process_ce(struct mem_ctl_info *mci, u16 error_one,
309052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			u32 sec1_add, u16 sec1_syndrome)
310806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
311806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u32 page;
312806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	int row;
313806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	int channel;
314806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	int i;
315203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	struct e752x_pvt *pvt = (struct e752x_pvt *)mci->pvt_info;
316806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
317537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson	debugf3("%s()\n", __func__);
318806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
319806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	/* convert the addr to 4k page */
320806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	page = sec1_add >> (PAGE_SHIFT - 4);
321806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
322806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	/* FIXME - check for -1 */
323806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	if (pvt->mc_symmetric) {
324806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		/* chip select are bits 14 & 13 */
325806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		row = ((page >> 1) & 3);
326537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson		e752x_printk(KERN_WARNING,
327052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			"Test row %d Table %d %d %d %d %d %d %d %d\n", row,
328052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			pvt->map[0], pvt->map[1], pvt->map[2], pvt->map[3],
329052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			pvt->map[4], pvt->map[5], pvt->map[6],
330052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			pvt->map[7]);
331806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
332806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		/* test for channel remapping */
333806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		for (i = 0; i < 8; i++) {
334806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox			if (pvt->map[i] == row)
335806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox				break;
336806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		}
337e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
338537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson		e752x_printk(KERN_WARNING, "Test computed row %d\n", i);
339e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
340806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		if (i < 8)
341806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox			row = i;
342806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		else
343537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson			e752x_mc_printk(mci, KERN_WARNING,
344203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang					"row %d not found in remap table\n",
345203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang					row);
346806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	} else
347806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		row = edac_mc_find_csrow_by_page(mci, page);
348e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
349806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	/* 0 = channel A, 1 = channel B */
350806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	channel = !(error_one & 1);
351806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
35284db003f249ddbcde1666376b4e3bbe9ee2c7c0cMike Chan	/* e752x mc reads 34:6 of the DRAM linear address */
35384db003f249ddbcde1666376b4e3bbe9ee2c7c0cMike Chan	edac_mc_handle_ce(mci, page, offset_in_page(sec1_add << 4),
354052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			sec1_syndrome, row, channel, "e752x CE");
355806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
356806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
357806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstatic inline void process_ce(struct mem_ctl_info *mci, u16 error_one,
358052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			u32 sec1_add, u16 sec1_syndrome, int *error_found,
359052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			int handle_error)
360806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
361806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	*error_found = 1;
362806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
363806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	if (handle_error)
364806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		do_process_ce(mci, error_one, sec1_add, sec1_syndrome);
365806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
366806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
367e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Petersonstatic void do_process_ue(struct mem_ctl_info *mci, u16 error_one,
368052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			u32 ded_add, u32 scrb_add)
369806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
370806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u32 error_2b, block_page;
371806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	int row;
372203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	struct e752x_pvt *pvt = (struct e752x_pvt *)mci->pvt_info;
373806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
374537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson	debugf3("%s()\n", __func__);
375806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
376806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	if (error_one & 0x0202) {
377806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		error_2b = ded_add;
378e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
379806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		/* convert to 4k address */
380806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		block_page = error_2b >> (PAGE_SHIFT - 4);
381e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
382806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		row = pvt->mc_symmetric ?
383052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson		/* chip select are bits 14 & 13 */
384052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			((block_page >> 1) & 3) :
385052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			edac_mc_find_csrow_by_page(mci, block_page);
386e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
38784db003f249ddbcde1666376b4e3bbe9ee2c7c0cMike Chan		/* e752x mc reads 34:6 of the DRAM linear address */
38884db003f249ddbcde1666376b4e3bbe9ee2c7c0cMike Chan		edac_mc_handle_ue(mci, block_page,
389052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				offset_in_page(error_2b << 4),
390052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				row, "e752x UE from Read");
391806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	}
392806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	if (error_one & 0x0404) {
393806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		error_2b = scrb_add;
394e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
395806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		/* convert to 4k address */
396806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		block_page = error_2b >> (PAGE_SHIFT - 4);
397e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
398806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		row = pvt->mc_symmetric ?
399052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson		/* chip select are bits 14 & 13 */
400052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			((block_page >> 1) & 3) :
401052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			edac_mc_find_csrow_by_page(mci, block_page);
402e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
40384db003f249ddbcde1666376b4e3bbe9ee2c7c0cMike Chan		/* e752x mc reads 34:6 of the DRAM linear address */
40484db003f249ddbcde1666376b4e3bbe9ee2c7c0cMike Chan		edac_mc_handle_ue(mci, block_page,
405052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				offset_in_page(error_2b << 4),
406052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				row, "e752x UE from Scruber");
407806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	}
408806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
409806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
410806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstatic inline void process_ue(struct mem_ctl_info *mci, u16 error_one,
411052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			u32 ded_add, u32 scrb_add, int *error_found,
412052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			int handle_error)
413806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
414806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	*error_found = 1;
415806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
416806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	if (handle_error)
417806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		do_process_ue(mci, error_one, ded_add, scrb_add);
418806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
419806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
420806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstatic inline void process_ue_no_info_wr(struct mem_ctl_info *mci,
421203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang					 int *error_found, int handle_error)
422806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
423806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	*error_found = 1;
424806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
425806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	if (!handle_error)
426806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		return;
427806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
428537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson	debugf3("%s()\n", __func__);
429806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	edac_mc_handle_ue_no_info(mci, "e752x UE log memory write");
430806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
431806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
432806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstatic void do_process_ded_retry(struct mem_ctl_info *mci, u16 error,
433203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang				 u32 retry_add)
434806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
435806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u32 error_1b, page;
436806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	int row;
437203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	struct e752x_pvt *pvt = (struct e752x_pvt *)mci->pvt_info;
438806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
439806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	error_1b = retry_add;
44010d33e9c36827e5371479e55ef4089e000af2638Doug Thompson	page = error_1b >> (PAGE_SHIFT - 4);  /* convert the addr to 4k page */
44110d33e9c36827e5371479e55ef4089e000af2638Doug Thompson
44210d33e9c36827e5371479e55ef4089e000af2638Doug Thompson	/* chip select are bits 14 & 13 */
44310d33e9c36827e5371479e55ef4089e000af2638Doug Thompson	row = pvt->mc_symmetric ? ((page >> 1) & 3) :
444052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson		edac_mc_find_csrow_by_page(mci, page);
44510d33e9c36827e5371479e55ef4089e000af2638Doug Thompson
446537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson	e752x_mc_printk(mci, KERN_WARNING,
447203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang			"CE page 0x%lx, row %d : Memory read retry\n",
448203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang			(long unsigned int)page, row);
449806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
450806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
451806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstatic inline void process_ded_retry(struct mem_ctl_info *mci, u16 error,
452052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				u32 retry_add, int *error_found,
453052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				int handle_error)
454806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
455806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	*error_found = 1;
456806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
457806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	if (handle_error)
458806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		do_process_ded_retry(mci, error, retry_add);
459806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
460806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
461806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstatic inline void process_threshold_ce(struct mem_ctl_info *mci, u16 error,
462203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang					int *error_found, int handle_error)
463806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
464806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	*error_found = 1;
465806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
466806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	if (handle_error)
467537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson		e752x_mc_printk(mci, KERN_WARNING, "Memory threshold CE\n");
468806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
469806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
470da9bb1d27b21cb24cbb6a2efb5d3c464d357a01eAlan Coxstatic char *global_message[11] = {
47110d33e9c36827e5371479e55ef4089e000af2638Doug Thompson	"PCI Express C1",
47210d33e9c36827e5371479e55ef4089e000af2638Doug Thompson	"PCI Express C",
47310d33e9c36827e5371479e55ef4089e000af2638Doug Thompson	"PCI Express B1",
47410d33e9c36827e5371479e55ef4089e000af2638Doug Thompson	"PCI Express B",
47510d33e9c36827e5371479e55ef4089e000af2638Doug Thompson	"PCI Express A1",
47610d33e9c36827e5371479e55ef4089e000af2638Doug Thompson	"PCI Express A",
47710d33e9c36827e5371479e55ef4089e000af2638Doug Thompson	"DMA Controller",
47810d33e9c36827e5371479e55ef4089e000af2638Doug Thompson	"HUB or NS Interface",
47910d33e9c36827e5371479e55ef4089e000af2638Doug Thompson	"System Bus",
48010d33e9c36827e5371479e55ef4089e000af2638Doug Thompson	"DRAM Controller",  /* 9th entry */
48110d33e9c36827e5371479e55ef4089e000af2638Doug Thompson	"Internal Buffer"
482806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox};
483806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
48410d33e9c36827e5371479e55ef4089e000af2638Doug Thompson#define DRAM_ENTRY	9
48510d33e9c36827e5371479e55ef4089e000af2638Doug Thompson
486da9bb1d27b21cb24cbb6a2efb5d3c464d357a01eAlan Coxstatic char *fatal_message[2] = { "Non-Fatal ", "Fatal " };
487806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
488806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstatic void do_global_error(int fatal, u32 errors)
489806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
490806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	int i;
491806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
492806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	for (i = 0; i < 11; i++) {
49310d33e9c36827e5371479e55ef4089e000af2638Doug Thompson		if (errors & (1 << i)) {
49410d33e9c36827e5371479e55ef4089e000af2638Doug Thompson			/* If the error is from DRAM Controller OR
49510d33e9c36827e5371479e55ef4089e000af2638Doug Thompson			 * we are to report ALL errors, then
49610d33e9c36827e5371479e55ef4089e000af2638Doug Thompson			 * report the error
49710d33e9c36827e5371479e55ef4089e000af2638Doug Thompson			 */
49810d33e9c36827e5371479e55ef4089e000af2638Doug Thompson			if ((i == DRAM_ENTRY) || report_non_memory_errors)
49910d33e9c36827e5371479e55ef4089e000af2638Doug Thompson				e752x_printk(KERN_WARNING, "%sError %s\n",
50010d33e9c36827e5371479e55ef4089e000af2638Doug Thompson					fatal_message[fatal],
50110d33e9c36827e5371479e55ef4089e000af2638Doug Thompson					global_message[i]);
50210d33e9c36827e5371479e55ef4089e000af2638Doug Thompson		}
503806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	}
504806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
505806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
506806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstatic inline void global_error(int fatal, u32 errors, int *error_found,
507203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang				int handle_error)
508806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
509806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	*error_found = 1;
510806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
511806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	if (handle_error)
512806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		do_global_error(fatal, errors);
513806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
514806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
515da9bb1d27b21cb24cbb6a2efb5d3c464d357a01eAlan Coxstatic char *hub_message[7] = {
516806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	"HI Address or Command Parity", "HI Illegal Access",
517806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	"HI Internal Parity", "Out of Range Access",
518806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	"HI Data Parity", "Enhanced Config Access",
519806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	"Hub Interface Target Abort"
520806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox};
521806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
522806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstatic void do_hub_error(int fatal, u8 errors)
523806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
524806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	int i;
525806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
526806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	for (i = 0; i < 7; i++) {
527806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		if (errors & (1 << i))
528537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson			e752x_printk(KERN_WARNING, "%sError %s\n",
529052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				fatal_message[fatal], hub_message[i]);
530806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	}
531806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
532806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
533806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstatic inline void hub_error(int fatal, u8 errors, int *error_found,
534052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			int handle_error)
535806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
536806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	*error_found = 1;
537806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
538806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	if (handle_error)
539806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		do_hub_error(fatal, errors);
540806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
541806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
5425135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov#define NSI_FATAL_MASK		0x0c080081
5435135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov#define NSI_NON_FATAL_MASK	0x23a0ba64
5445135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov#define NSI_ERR_MASK		(NSI_FATAL_MASK | NSI_NON_FATAL_MASK)
5455135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov
5465135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalovstatic char *nsi_message[30] = {
5475135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"NSI Link Down",	/* NSI_FERR/NSI_NERR bit 0, fatal error */
5485135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"",						/* reserved */
5495135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"NSI Parity Error",				/* bit 2, non-fatal */
5505135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"",						/* reserved */
5515135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"",						/* reserved */
5525135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"Correctable Error Message",			/* bit 5, non-fatal */
5535135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"Non-Fatal Error Message",			/* bit 6, non-fatal */
5545135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"Fatal Error Message",				/* bit 7, fatal */
5555135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"",						/* reserved */
5565135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"Receiver Error",				/* bit 9, non-fatal */
5575135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"",						/* reserved */
5585135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"Bad TLP",					/* bit 11, non-fatal */
5595135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"Bad DLLP",					/* bit 12, non-fatal */
5605135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"REPLAY_NUM Rollover",				/* bit 13, non-fatal */
5615135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"",						/* reserved */
5625135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"Replay Timer Timeout",				/* bit 15, non-fatal */
5635135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"",						/* reserved */
5645135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"",						/* reserved */
5655135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"",						/* reserved */
5665135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"Data Link Protocol Error",			/* bit 19, fatal */
5675135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"",						/* reserved */
5685135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"Poisoned TLP",					/* bit 21, non-fatal */
5695135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"",						/* reserved */
5705135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"Completion Timeout",				/* bit 23, non-fatal */
5715135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"Completer Abort",				/* bit 24, non-fatal */
5725135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"Unexpected Completion",			/* bit 25, non-fatal */
5735135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"Receiver Overflow",				/* bit 26, fatal */
5745135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"Malformed TLP",				/* bit 27, fatal */
5755135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"",						/* reserved */
5765135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	"Unsupported Request"				/* bit 29, non-fatal */
5775135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov};
5785135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov
5795135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalovstatic void do_nsi_error(int fatal, u32 errors)
5805135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov{
5815135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	int i;
5825135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov
5835135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	for (i = 0; i < 30; i++) {
5845135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		if (errors & (1 << i))
5855135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov			printk(KERN_WARNING "%sError %s\n",
5865135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov			       fatal_message[fatal], nsi_message[i]);
5875135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	}
5885135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov}
5895135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov
5905135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalovstatic inline void nsi_error(int fatal, u32 errors, int *error_found,
5915135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		int handle_error)
5925135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov{
5935135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	*error_found = 1;
5945135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov
5955135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	if (handle_error)
5965135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		do_nsi_error(fatal, errors);
5975135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov}
5985135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov
599da9bb1d27b21cb24cbb6a2efb5d3c464d357a01eAlan Coxstatic char *membuf_message[4] = {
600806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	"Internal PMWB to DRAM parity",
601806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	"Internal PMWB to System Bus Parity",
602806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	"Internal System Bus or IO to PMWB Parity",
603806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	"Internal DRAM to PMWB Parity"
604806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox};
605806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
606806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstatic void do_membuf_error(u8 errors)
607806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
608806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	int i;
609806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
610806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	for (i = 0; i < 4; i++) {
611806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		if (errors & (1 << i))
612537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson			e752x_printk(KERN_WARNING, "Non-Fatal Error %s\n",
613052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				membuf_message[i]);
614806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	}
615806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
616806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
617806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstatic inline void membuf_error(u8 errors, int *error_found, int handle_error)
618806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
619806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	*error_found = 1;
620806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
621806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	if (handle_error)
622806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		do_membuf_error(errors);
623806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
624806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
625e009356f738634d8a137cca35503b9b33322c858Dave Petersonstatic char *sysbus_message[10] = {
626806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	"Addr or Request Parity",
627806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	"Data Strobe Glitch",
628806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	"Addr Strobe Glitch",
629806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	"Data Parity",
630806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	"Addr Above TOM",
631806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	"Non DRAM Lock Error",
632806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	"MCERR", "BINIT",
633806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	"Memory Parity",
634806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	"IO Subsystem Parity"
635806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox};
636806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
637806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstatic void do_sysbus_error(int fatal, u32 errors)
638806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
639806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	int i;
640806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
641806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	for (i = 0; i < 10; i++) {
642806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		if (errors & (1 << i))
643537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson			e752x_printk(KERN_WARNING, "%sError System Bus %s\n",
644052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				fatal_message[fatal], sysbus_message[i]);
645806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	}
646806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
647806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
648806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstatic inline void sysbus_error(int fatal, u32 errors, int *error_found,
649203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang				int handle_error)
650806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
651806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	*error_found = 1;
652806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
653806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	if (handle_error)
654806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		do_sysbus_error(fatal, errors);
655806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
656806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
657e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Petersonstatic void e752x_check_hub_interface(struct e752x_error_info *info,
658052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				int *error_found, int handle_error)
659806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
660806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u8 stat8;
661806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
662806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	//pci_read_config_byte(dev,E752X_HI_FERR,&stat8);
663e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
664806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	stat8 = info->hi_ferr;
665e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
666203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	if (stat8 & 0x7f) {	/* Error, so process */
667806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		stat8 &= 0x7f;
668e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
669203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang		if (stat8 & 0x2b)
670806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox			hub_error(1, stat8 & 0x2b, error_found, handle_error);
671e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
672203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang		if (stat8 & 0x54)
673806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox			hub_error(0, stat8 & 0x54, error_found, handle_error);
674806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	}
675806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	//pci_read_config_byte(dev,E752X_HI_NERR,&stat8);
676e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
677806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	stat8 = info->hi_nerr;
678e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
679203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	if (stat8 & 0x7f) {	/* Error, so process */
680806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		stat8 &= 0x7f;
681e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
682806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		if (stat8 & 0x2b)
683806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox			hub_error(1, stat8 & 0x2b, error_found, handle_error);
684e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
685203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang		if (stat8 & 0x54)
686806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox			hub_error(0, stat8 & 0x54, error_found, handle_error);
687806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	}
688806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
689806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
6905135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalovstatic void e752x_check_ns_interface(struct e752x_error_info *info,
6915135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov				int *error_found, int handle_error)
6925135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov{
6935135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	u32 stat32;
6945135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov
6955135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	stat32 = info->nsi_ferr;
6965135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	if (stat32 & NSI_ERR_MASK) { /* Error, so process */
6975135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		if (stat32 & NSI_FATAL_MASK)	/* check for fatal errors */
6985135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov			nsi_error(1, stat32 & NSI_FATAL_MASK, error_found,
6995135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov				  handle_error);
7005135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		if (stat32 & NSI_NON_FATAL_MASK) /* check for non-fatal ones */
7015135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov			nsi_error(0, stat32 & NSI_NON_FATAL_MASK, error_found,
7025135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov				  handle_error);
7035135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	}
7045135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	stat32 = info->nsi_nerr;
7055135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	if (stat32 & NSI_ERR_MASK) {
7065135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		if (stat32 & NSI_FATAL_MASK)
7075135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov			nsi_error(1, stat32 & NSI_FATAL_MASK, error_found,
7085135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov				  handle_error);
7095135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		if (stat32 & NSI_NON_FATAL_MASK)
7105135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov			nsi_error(0, stat32 & NSI_NON_FATAL_MASK, error_found,
7115135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov				  handle_error);
7125135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	}
7135135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov}
7145135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov
715e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Petersonstatic void e752x_check_sysbus(struct e752x_error_info *info,
716052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			int *error_found, int handle_error)
717806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
718806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u32 stat32, error32;
719806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
720806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	//pci_read_config_dword(dev,E752X_SYSBUS_FERR,&stat32);
721806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	stat32 = info->sysbus_ferr + (info->sysbus_nerr << 16);
722806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
723806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	if (stat32 == 0)
724203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang		return;		/* no errors */
725806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
726806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	error32 = (stat32 >> 16) & 0x3ff;
727806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	stat32 = stat32 & 0x3ff;
728e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
729203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	if (stat32 & 0x087)
730dfb2a76378f095b0aaa2024ce9a8cfb2ae2354d2Brian Pomerantz		sysbus_error(1, stat32 & 0x087, error_found, handle_error);
731e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
732203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	if (stat32 & 0x378)
733dfb2a76378f095b0aaa2024ce9a8cfb2ae2354d2Brian Pomerantz		sysbus_error(0, stat32 & 0x378, error_found, handle_error);
734e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
735203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	if (error32 & 0x087)
736dfb2a76378f095b0aaa2024ce9a8cfb2ae2354d2Brian Pomerantz		sysbus_error(1, error32 & 0x087, error_found, handle_error);
737e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
738203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	if (error32 & 0x378)
739dfb2a76378f095b0aaa2024ce9a8cfb2ae2354d2Brian Pomerantz		sysbus_error(0, error32 & 0x378, error_found, handle_error);
740806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
741806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
742203333cbbaae3941504c2b6e92850783bf361b6fDave Jiangstatic void e752x_check_membuf(struct e752x_error_info *info,
743052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			int *error_found, int handle_error)
744806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
745806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u8 stat8;
746806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
747806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	stat8 = info->buf_ferr;
748e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
749203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	if (stat8 & 0x0f) {	/* Error, so process */
750806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		stat8 &= 0x0f;
751806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		membuf_error(stat8, error_found, handle_error);
752806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	}
753e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
754806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	stat8 = info->buf_nerr;
755e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
756203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	if (stat8 & 0x0f) {	/* Error, so process */
757806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		stat8 &= 0x0f;
758806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		membuf_error(stat8, error_found, handle_error);
759806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	}
760806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
761806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
762203333cbbaae3941504c2b6e92850783bf361b6fDave Jiangstatic void e752x_check_dram(struct mem_ctl_info *mci,
763052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			struct e752x_error_info *info, int *error_found,
764052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			int handle_error)
765806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
766806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u16 error_one, error_next;
767806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
768806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	error_one = info->dram_ferr;
769806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	error_next = info->dram_nerr;
770806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
771806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	/* decode and report errors */
772203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	if (error_one & 0x0101)	/* check first error correctable */
773806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		process_ce(mci, error_one, info->dram_sec1_add,
774052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			info->dram_sec1_syndrome, error_found, handle_error);
775806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
776203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	if (error_next & 0x0101)	/* check next error correctable */
777806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		process_ce(mci, error_next, info->dram_sec2_add,
778052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			info->dram_sec2_syndrome, error_found, handle_error);
779806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
780203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	if (error_one & 0x4040)
781806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		process_ue_no_info_wr(mci, error_found, handle_error);
782806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
783203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	if (error_next & 0x4040)
784806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		process_ue_no_info_wr(mci, error_found, handle_error);
785806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
786203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	if (error_one & 0x2020)
787806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		process_ded_retry(mci, error_one, info->dram_retr_add,
788052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				error_found, handle_error);
789806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
790203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	if (error_next & 0x2020)
791806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		process_ded_retry(mci, error_next, info->dram_retr_add,
792052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				error_found, handle_error);
793806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
794203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	if (error_one & 0x0808)
795203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang		process_threshold_ce(mci, error_one, error_found, handle_error);
796806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
797203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	if (error_next & 0x0808)
798806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		process_threshold_ce(mci, error_next, error_found,
799052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				handle_error);
800806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
801203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	if (error_one & 0x0606)
802806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		process_ue(mci, error_one, info->dram_ded_add,
803052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			info->dram_scrb_add, error_found, handle_error);
804806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
805203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	if (error_next & 0x0606)
806806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		process_ue(mci, error_next, info->dram_ded_add,
807052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			info->dram_scrb_add, error_found, handle_error);
808806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
809806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
810203333cbbaae3941504c2b6e92850783bf361b6fDave Jiangstatic void e752x_get_error_info(struct mem_ctl_info *mci,
811203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang				 struct e752x_error_info *info)
812806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
813806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	struct pci_dev *dev;
814806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	struct e752x_pvt *pvt;
815806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
816806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	memset(info, 0, sizeof(*info));
817203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	pvt = (struct e752x_pvt *)mci->pvt_info;
818806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	dev = pvt->dev_d0f1;
819806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	pci_read_config_dword(dev, E752X_FERR_GLOBAL, &info->ferr_global);
820806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
821806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	if (info->ferr_global) {
8225135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		if (pvt->dev_info->err_dev == PCI_DEVICE_ID_INTEL_3100_1_ERR) {
8235135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov			pci_read_config_dword(dev, I3100_NSI_FERR,
8245135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov					     &info->nsi_ferr);
8255135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov			info->hi_ferr = 0;
8265135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		} else {
8275135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov			pci_read_config_byte(dev, E752X_HI_FERR,
8285135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov					     &info->hi_ferr);
8295135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov			info->nsi_ferr = 0;
8305135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		}
831806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		pci_read_config_word(dev, E752X_SYSBUS_FERR,
832052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				&info->sysbus_ferr);
833806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		pci_read_config_byte(dev, E752X_BUF_FERR, &info->buf_ferr);
834203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang		pci_read_config_word(dev, E752X_DRAM_FERR, &info->dram_ferr);
835806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		pci_read_config_dword(dev, E752X_DRAM_SEC1_ADD,
836052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				&info->dram_sec1_add);
837806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		pci_read_config_word(dev, E752X_DRAM_SEC1_SYNDROME,
838052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				&info->dram_sec1_syndrome);
839806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		pci_read_config_dword(dev, E752X_DRAM_DED_ADD,
840052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				&info->dram_ded_add);
841806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		pci_read_config_dword(dev, E752X_DRAM_SCRB_ADD,
842052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				&info->dram_scrb_add);
843806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		pci_read_config_dword(dev, E752X_DRAM_RETR_ADD,
844052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				&info->dram_retr_add);
845806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
8465135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		/* ignore the reserved bits just in case */
847806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		if (info->hi_ferr & 0x7f)
848806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox			pci_write_config_byte(dev, E752X_HI_FERR,
849052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson					info->hi_ferr);
850806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
8515135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		if (info->nsi_ferr & NSI_ERR_MASK)
8525135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov			pci_write_config_dword(dev, I3100_NSI_FERR,
8535135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov					info->nsi_ferr);
8545135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov
855806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		if (info->sysbus_ferr)
856806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox			pci_write_config_word(dev, E752X_SYSBUS_FERR,
857052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson					info->sysbus_ferr);
858806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
859806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		if (info->buf_ferr & 0x0f)
860806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox			pci_write_config_byte(dev, E752X_BUF_FERR,
861052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson					info->buf_ferr);
862806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
863806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		if (info->dram_ferr)
864806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox			pci_write_bits16(pvt->bridge_ck, E752X_DRAM_FERR,
865203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang					 info->dram_ferr, info->dram_ferr);
866806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
867806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		pci_write_config_dword(dev, E752X_FERR_GLOBAL,
868052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				info->ferr_global);
869806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	}
870806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
871806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	pci_read_config_dword(dev, E752X_NERR_GLOBAL, &info->nerr_global);
872806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
873806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	if (info->nerr_global) {
8745135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		if (pvt->dev_info->err_dev == PCI_DEVICE_ID_INTEL_3100_1_ERR) {
8755135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov			pci_read_config_dword(dev, I3100_NSI_NERR,
8765135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov					     &info->nsi_nerr);
8775135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov			info->hi_nerr = 0;
8785135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		} else {
8795135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov			pci_read_config_byte(dev, E752X_HI_NERR,
8805135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov					     &info->hi_nerr);
8815135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov			info->nsi_nerr = 0;
8825135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		}
883806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		pci_read_config_word(dev, E752X_SYSBUS_NERR,
884052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				&info->sysbus_nerr);
885806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		pci_read_config_byte(dev, E752X_BUF_NERR, &info->buf_nerr);
886203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang		pci_read_config_word(dev, E752X_DRAM_NERR, &info->dram_nerr);
887806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		pci_read_config_dword(dev, E752X_DRAM_SEC2_ADD,
888052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				&info->dram_sec2_add);
889806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		pci_read_config_word(dev, E752X_DRAM_SEC2_SYNDROME,
890052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				&info->dram_sec2_syndrome);
891806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
892806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		if (info->hi_nerr & 0x7f)
893806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox			pci_write_config_byte(dev, E752X_HI_NERR,
894052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson					info->hi_nerr);
895806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
8965135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		if (info->nsi_nerr & NSI_ERR_MASK)
8975135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov			pci_write_config_dword(dev, I3100_NSI_NERR,
8985135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov					info->nsi_nerr);
8995135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov
900806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		if (info->sysbus_nerr)
901806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox			pci_write_config_word(dev, E752X_SYSBUS_NERR,
902052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson					info->sysbus_nerr);
903806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
904806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		if (info->buf_nerr & 0x0f)
905806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox			pci_write_config_byte(dev, E752X_BUF_NERR,
906052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson					info->buf_nerr);
907806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
908806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		if (info->dram_nerr)
909806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox			pci_write_bits16(pvt->bridge_ck, E752X_DRAM_NERR,
910203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang					 info->dram_nerr, info->dram_nerr);
911806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
912806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		pci_write_config_dword(dev, E752X_NERR_GLOBAL,
913052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				info->nerr_global);
914806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	}
915806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
916806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
917203333cbbaae3941504c2b6e92850783bf361b6fDave Jiangstatic int e752x_process_error_info(struct mem_ctl_info *mci,
918052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				struct e752x_error_info *info,
919052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				int handle_errors)
920806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
921806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u32 error32, stat32;
922806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	int error_found;
923806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
924806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	error_found = 0;
925806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	error32 = (info->ferr_global >> 18) & 0x3ff;
926806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	stat32 = (info->ferr_global >> 4) & 0x7ff;
927806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
928806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	if (error32)
929806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		global_error(1, error32, &error_found, handle_errors);
930806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
931806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	if (stat32)
932806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		global_error(0, stat32, &error_found, handle_errors);
933806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
934806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	error32 = (info->nerr_global >> 18) & 0x3ff;
935806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	stat32 = (info->nerr_global >> 4) & 0x7ff;
936806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
937806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	if (error32)
938806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		global_error(1, error32, &error_found, handle_errors);
939806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
940806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	if (stat32)
941806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		global_error(0, stat32, &error_found, handle_errors);
942806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
943806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	e752x_check_hub_interface(info, &error_found, handle_errors);
9445135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	e752x_check_ns_interface(info, &error_found, handle_errors);
945806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	e752x_check_sysbus(info, &error_found, handle_errors);
946806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	e752x_check_membuf(info, &error_found, handle_errors);
947806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	e752x_check_dram(mci, info, &error_found, handle_errors);
948806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	return error_found;
949806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
950806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
951806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstatic void e752x_check(struct mem_ctl_info *mci)
952806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
953806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	struct e752x_error_info info;
954e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
955537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson	debugf3("%s()\n", __func__);
956806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	e752x_get_error_info(mci, &info);
957806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	e752x_process_error_info(mci, &info, 1);
958806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
959806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
9608004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser/* Program byte/sec bandwidth scrub rate to hardware */
961eba042a81edd6baaff44831b2d719b14a6d21e58Borislav Petkovstatic int set_sdram_scrub_rate(struct mem_ctl_info *mci, u32 new_bw)
9628004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser{
9638004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	const struct scrubrate *scrubrates;
9648004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	struct e752x_pvt *pvt = (struct e752x_pvt *) mci->pvt_info;
9658004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	struct pci_dev *pdev = pvt->dev_d0f0;
9668004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	int i;
9678004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser
9688004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	if (pvt->dev_info->ctl_dev == PCI_DEVICE_ID_INTEL_3100_0)
9698004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser		scrubrates = scrubrates_i3100;
9708004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	else
9718004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser		scrubrates = scrubrates_e752x;
9728004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser
9738004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	/* Translate the desired scrub rate to a e752x/3100 register value.
9748004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	 * Search for the bandwidth that is equal or greater than the
9758004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	 * desired rate and program the cooresponding register value.
9768004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	 */
9778004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	for (i = 0; scrubrates[i].bandwidth != SDRATE_EOT; i++)
978eba042a81edd6baaff44831b2d719b14a6d21e58Borislav Petkov		if (scrubrates[i].bandwidth >= new_bw)
9798004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser			break;
9808004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser
9818004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	if (scrubrates[i].bandwidth == SDRATE_EOT)
9828004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser		return -1;
9838004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser
9848004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	pci_write_config_word(pdev, E752X_MCHSCRB, scrubrates[i].scrubval);
9858004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser
986390944439f746824faec51b576f50cb5ef18745bBorislav Petkov	return scrubrates[i].bandwidth;
9878004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser}
9888004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser
9898004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser/* Convert current scrub rate value into byte/sec bandwidth */
990390944439f746824faec51b576f50cb5ef18745bBorislav Petkovstatic int get_sdram_scrub_rate(struct mem_ctl_info *mci)
9918004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser{
9928004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	const struct scrubrate *scrubrates;
9938004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	struct e752x_pvt *pvt = (struct e752x_pvt *) mci->pvt_info;
9948004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	struct pci_dev *pdev = pvt->dev_d0f0;
9958004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	u16 scrubval;
9968004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	int i;
9978004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser
9988004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	if (pvt->dev_info->ctl_dev == PCI_DEVICE_ID_INTEL_3100_0)
9998004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser		scrubrates = scrubrates_i3100;
10008004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	else
10018004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser		scrubrates = scrubrates_e752x;
10028004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser
10038004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	/* Find the bandwidth matching the memory scrubber configuration */
10048004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	pci_read_config_word(pdev, E752X_MCHSCRB, &scrubval);
10058004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	scrubval = scrubval & 0x0f;
10068004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser
10078004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	for (i = 0; scrubrates[i].bandwidth != SDRATE_EOT; i++)
10088004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser		if (scrubrates[i].scrubval == scrubval)
10098004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser			break;
10108004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser
10118004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	if (scrubrates[i].bandwidth == SDRATE_EOT) {
10128004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser		e752x_printk(KERN_WARNING,
10138004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser			"Invalid sdram scrub control value: 0x%x\n", scrubval);
10148004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser		return -1;
10158004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	}
1016390944439f746824faec51b576f50cb5ef18745bBorislav Petkov	return scrubrates[i].bandwidth;
10178004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser
10188004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser}
10198004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser
10201318952514d5651c453d89989595a9df3b37267bDoug Thompson/* Return 1 if dual channel mode is active.  Else return 0. */
10211318952514d5651c453d89989595a9df3b37267bDoug Thompsonstatic inline int dual_channel_active(u16 ddrcsr)
10221318952514d5651c453d89989595a9df3b37267bDoug Thompson{
10231318952514d5651c453d89989595a9df3b37267bDoug Thompson	return (((ddrcsr >> 12) & 3) == 3);
10241318952514d5651c453d89989595a9df3b37267bDoug Thompson}
10251318952514d5651c453d89989595a9df3b37267bDoug Thompson
10267297c2617f6465d7862e156d4db5d812744280f1Mark Grondona/* Remap csrow index numbers if map_type is "reverse"
10277297c2617f6465d7862e156d4db5d812744280f1Mark Grondona */
10287297c2617f6465d7862e156d4db5d812744280f1Mark Grondonastatic inline int remap_csrow_index(struct mem_ctl_info *mci, int index)
10297297c2617f6465d7862e156d4db5d812744280f1Mark Grondona{
10307297c2617f6465d7862e156d4db5d812744280f1Mark Grondona	struct e752x_pvt *pvt = mci->pvt_info;
10317297c2617f6465d7862e156d4db5d812744280f1Mark Grondona
10327297c2617f6465d7862e156d4db5d812744280f1Mark Grondona	if (!pvt->map_type)
10337297c2617f6465d7862e156d4db5d812744280f1Mark Grondona		return (7 - index);
10347297c2617f6465d7862e156d4db5d812744280f1Mark Grondona
10357297c2617f6465d7862e156d4db5d812744280f1Mark Grondona	return (index);
10367297c2617f6465d7862e156d4db5d812744280f1Mark Grondona}
10377297c2617f6465d7862e156d4db5d812744280f1Mark Grondona
10381318952514d5651c453d89989595a9df3b37267bDoug Thompsonstatic void e752x_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev,
1039052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			u16 ddrcsr)
10401318952514d5651c453d89989595a9df3b37267bDoug Thompson{
10411318952514d5651c453d89989595a9df3b37267bDoug Thompson	struct csrow_info *csrow;
10421318952514d5651c453d89989595a9df3b37267bDoug Thompson	unsigned long last_cumul_size;
10431318952514d5651c453d89989595a9df3b37267bDoug Thompson	int index, mem_dev, drc_chan;
1044203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	int drc_drbg;		/* DRB granularity 0=64mb, 1=128mb */
1045203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	int drc_ddim;		/* DRAM Data Integrity Mode 0=none, 2=edac */
10461318952514d5651c453d89989595a9df3b37267bDoug Thompson	u8 value;
10471318952514d5651c453d89989595a9df3b37267bDoug Thompson	u32 dra, drc, cumul_size;
10481318952514d5651c453d89989595a9df3b37267bDoug Thompson
10499962fd017becf944d671da498ccaaea570452206Brian Pomerantz	dra = 0;
1050203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	for (index = 0; index < 4; index++) {
10519962fd017becf944d671da498ccaaea570452206Brian Pomerantz		u8 dra_reg;
1052203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang		pci_read_config_byte(pdev, E752X_DRA + index, &dra_reg);
10539962fd017becf944d671da498ccaaea570452206Brian Pomerantz		dra |= dra_reg << (index * 8);
10549962fd017becf944d671da498ccaaea570452206Brian Pomerantz	}
10551318952514d5651c453d89989595a9df3b37267bDoug Thompson	pci_read_config_dword(pdev, E752X_DRC, &drc);
10561318952514d5651c453d89989595a9df3b37267bDoug Thompson	drc_chan = dual_channel_active(ddrcsr);
1057203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	drc_drbg = drc_chan + 1;	/* 128 in dual mode, 64 in single */
10581318952514d5651c453d89989595a9df3b37267bDoug Thompson	drc_ddim = (drc >> 20) & 0x3;
10591318952514d5651c453d89989595a9df3b37267bDoug Thompson
10601318952514d5651c453d89989595a9df3b37267bDoug Thompson	/* The dram row boundary (DRB) reg values are boundary address for
10611318952514d5651c453d89989595a9df3b37267bDoug Thompson	 * each DRAM row with a granularity of 64 or 128MB (single/dual
10621318952514d5651c453d89989595a9df3b37267bDoug Thompson	 * channel operation).  DRB regs are cumulative; therefore DRB7 will
10631318952514d5651c453d89989595a9df3b37267bDoug Thompson	 * contain the total memory contained in all eight rows.
10641318952514d5651c453d89989595a9df3b37267bDoug Thompson	 */
10651318952514d5651c453d89989595a9df3b37267bDoug Thompson	for (last_cumul_size = index = 0; index < mci->nr_csrows; index++) {
10661318952514d5651c453d89989595a9df3b37267bDoug Thompson		/* mem_dev 0=x8, 1=x4 */
10671318952514d5651c453d89989595a9df3b37267bDoug Thompson		mem_dev = (dra >> (index * 4 + 2)) & 0x3;
10687297c2617f6465d7862e156d4db5d812744280f1Mark Grondona		csrow = &mci->csrows[remap_csrow_index(mci, index)];
10691318952514d5651c453d89989595a9df3b37267bDoug Thompson
10701318952514d5651c453d89989595a9df3b37267bDoug Thompson		mem_dev = (mem_dev == 2);
10711318952514d5651c453d89989595a9df3b37267bDoug Thompson		pci_read_config_byte(pdev, E752X_DRB + index, &value);
10721318952514d5651c453d89989595a9df3b37267bDoug Thompson		/* convert a 128 or 64 MiB DRB to a page size. */
10731318952514d5651c453d89989595a9df3b37267bDoug Thompson		cumul_size = value << (25 + drc_drbg - PAGE_SHIFT);
10741318952514d5651c453d89989595a9df3b37267bDoug Thompson		debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index,
10751318952514d5651c453d89989595a9df3b37267bDoug Thompson			cumul_size);
10761318952514d5651c453d89989595a9df3b37267bDoug Thompson		if (cumul_size == last_cumul_size)
10771318952514d5651c453d89989595a9df3b37267bDoug Thompson			continue;	/* not populated */
10781318952514d5651c453d89989595a9df3b37267bDoug Thompson
10791318952514d5651c453d89989595a9df3b37267bDoug Thompson		csrow->first_page = last_cumul_size;
10801318952514d5651c453d89989595a9df3b37267bDoug Thompson		csrow->last_page = cumul_size - 1;
10811318952514d5651c453d89989595a9df3b37267bDoug Thompson		csrow->nr_pages = cumul_size - last_cumul_size;
10821318952514d5651c453d89989595a9df3b37267bDoug Thompson		last_cumul_size = cumul_size;
10831318952514d5651c453d89989595a9df3b37267bDoug Thompson		csrow->grain = 1 << 12;	/* 4KiB - resolution of CELOG */
10841318952514d5651c453d89989595a9df3b37267bDoug Thompson		csrow->mtype = MEM_RDDR;	/* only one type supported */
10851318952514d5651c453d89989595a9df3b37267bDoug Thompson		csrow->dtype = mem_dev ? DEV_X4 : DEV_X8;
10861318952514d5651c453d89989595a9df3b37267bDoug Thompson
10871318952514d5651c453d89989595a9df3b37267bDoug Thompson		/*
10881318952514d5651c453d89989595a9df3b37267bDoug Thompson		 * if single channel or x8 devices then SECDED
10891318952514d5651c453d89989595a9df3b37267bDoug Thompson		 * if dual channel and x4 then S4ECD4ED
10901318952514d5651c453d89989595a9df3b37267bDoug Thompson		 */
10911318952514d5651c453d89989595a9df3b37267bDoug Thompson		if (drc_ddim) {
10921318952514d5651c453d89989595a9df3b37267bDoug Thompson			if (drc_chan && mem_dev) {
10931318952514d5651c453d89989595a9df3b37267bDoug Thompson				csrow->edac_mode = EDAC_S4ECD4ED;
10941318952514d5651c453d89989595a9df3b37267bDoug Thompson				mci->edac_cap |= EDAC_FLAG_S4ECD4ED;
10951318952514d5651c453d89989595a9df3b37267bDoug Thompson			} else {
10961318952514d5651c453d89989595a9df3b37267bDoug Thompson				csrow->edac_mode = EDAC_SECDED;
10971318952514d5651c453d89989595a9df3b37267bDoug Thompson				mci->edac_cap |= EDAC_FLAG_SECDED;
10981318952514d5651c453d89989595a9df3b37267bDoug Thompson			}
10991318952514d5651c453d89989595a9df3b37267bDoug Thompson		} else
11001318952514d5651c453d89989595a9df3b37267bDoug Thompson			csrow->edac_mode = EDAC_NONE;
11011318952514d5651c453d89989595a9df3b37267bDoug Thompson	}
11021318952514d5651c453d89989595a9df3b37267bDoug Thompson}
11031318952514d5651c453d89989595a9df3b37267bDoug Thompson
11041318952514d5651c453d89989595a9df3b37267bDoug Thompsonstatic void e752x_init_mem_map_table(struct pci_dev *pdev,
1105052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				struct e752x_pvt *pvt)
1106806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
1107806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	int index;
11087297c2617f6465d7862e156d4db5d812744280f1Mark Grondona	u8 value, last, row;
11091318952514d5651c453d89989595a9df3b37267bDoug Thompson
11101318952514d5651c453d89989595a9df3b37267bDoug Thompson	last = 0;
11111318952514d5651c453d89989595a9df3b37267bDoug Thompson	row = 0;
11121318952514d5651c453d89989595a9df3b37267bDoug Thompson
11131318952514d5651c453d89989595a9df3b37267bDoug Thompson	for (index = 0; index < 8; index += 2) {
11141318952514d5651c453d89989595a9df3b37267bDoug Thompson		pci_read_config_byte(pdev, E752X_DRB + index, &value);
11151318952514d5651c453d89989595a9df3b37267bDoug Thompson		/* test if there is a dimm in this slot */
11161318952514d5651c453d89989595a9df3b37267bDoug Thompson		if (value == last) {
11171318952514d5651c453d89989595a9df3b37267bDoug Thompson			/* no dimm in the slot, so flag it as empty */
11181318952514d5651c453d89989595a9df3b37267bDoug Thompson			pvt->map[index] = 0xff;
11191318952514d5651c453d89989595a9df3b37267bDoug Thompson			pvt->map[index + 1] = 0xff;
1120203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang		} else {	/* there is a dimm in the slot */
11211318952514d5651c453d89989595a9df3b37267bDoug Thompson			pvt->map[index] = row;
11221318952514d5651c453d89989595a9df3b37267bDoug Thompson			row++;
11231318952514d5651c453d89989595a9df3b37267bDoug Thompson			last = value;
11241318952514d5651c453d89989595a9df3b37267bDoug Thompson			/* test the next value to see if the dimm is double
11251318952514d5651c453d89989595a9df3b37267bDoug Thompson			 * sided
11261318952514d5651c453d89989595a9df3b37267bDoug Thompson			 */
11271318952514d5651c453d89989595a9df3b37267bDoug Thompson			pci_read_config_byte(pdev, E752X_DRB + index + 1,
1128052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson					&value);
1129052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson
1130052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			/* the dimm is single sided, so flag as empty */
1131052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			/* this is a double sided dimm to save the next row #*/
1132052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			pvt->map[index + 1] = (value == last) ? 0xff :	row;
11331318952514d5651c453d89989595a9df3b37267bDoug Thompson			row++;
11341318952514d5651c453d89989595a9df3b37267bDoug Thompson			last = value;
11351318952514d5651c453d89989595a9df3b37267bDoug Thompson		}
11361318952514d5651c453d89989595a9df3b37267bDoug Thompson	}
11371318952514d5651c453d89989595a9df3b37267bDoug Thompson}
11381318952514d5651c453d89989595a9df3b37267bDoug Thompson
11391318952514d5651c453d89989595a9df3b37267bDoug Thompson/* Return 0 on success or 1 on failure. */
11401318952514d5651c453d89989595a9df3b37267bDoug Thompsonstatic int e752x_get_devs(struct pci_dev *pdev, int dev_idx,
1141052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			struct e752x_pvt *pvt)
11421318952514d5651c453d89989595a9df3b37267bDoug Thompson{
11431318952514d5651c453d89989595a9df3b37267bDoug Thompson	struct pci_dev *dev;
11441318952514d5651c453d89989595a9df3b37267bDoug Thompson
11451318952514d5651c453d89989595a9df3b37267bDoug Thompson	pvt->bridge_ck = pci_get_device(PCI_VENDOR_ID_INTEL,
114610d33e9c36827e5371479e55ef4089e000af2638Doug Thompson				pvt->dev_info->err_dev, pvt->bridge_ck);
11471318952514d5651c453d89989595a9df3b37267bDoug Thompson
11481318952514d5651c453d89989595a9df3b37267bDoug Thompson	if (pvt->bridge_ck == NULL)
11491318952514d5651c453d89989595a9df3b37267bDoug Thompson		pvt->bridge_ck = pci_scan_single_device(pdev->bus,
11501318952514d5651c453d89989595a9df3b37267bDoug Thompson							PCI_DEVFN(0, 1));
11511318952514d5651c453d89989595a9df3b37267bDoug Thompson
11521318952514d5651c453d89989595a9df3b37267bDoug Thompson	if (pvt->bridge_ck == NULL) {
11531318952514d5651c453d89989595a9df3b37267bDoug Thompson		e752x_printk(KERN_ERR, "error reporting device not found:"
1154052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			"vendor %x device 0x%x (broken BIOS?)\n",
1155052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			PCI_VENDOR_ID_INTEL, e752x_devs[dev_idx].err_dev);
11561318952514d5651c453d89989595a9df3b37267bDoug Thompson		return 1;
11571318952514d5651c453d89989595a9df3b37267bDoug Thompson	}
11581318952514d5651c453d89989595a9df3b37267bDoug Thompson
115910d33e9c36827e5371479e55ef4089e000af2638Doug Thompson	dev = pci_get_device(PCI_VENDOR_ID_INTEL,
116010d33e9c36827e5371479e55ef4089e000af2638Doug Thompson				e752x_devs[dev_idx].ctl_dev,
116110d33e9c36827e5371479e55ef4089e000af2638Doug Thompson				NULL);
11621318952514d5651c453d89989595a9df3b37267bDoug Thompson
11631318952514d5651c453d89989595a9df3b37267bDoug Thompson	if (dev == NULL)
11641318952514d5651c453d89989595a9df3b37267bDoug Thompson		goto fail;
11651318952514d5651c453d89989595a9df3b37267bDoug Thompson
11661318952514d5651c453d89989595a9df3b37267bDoug Thompson	pvt->dev_d0f0 = dev;
11671318952514d5651c453d89989595a9df3b37267bDoug Thompson	pvt->dev_d0f1 = pci_dev_get(pvt->bridge_ck);
11681318952514d5651c453d89989595a9df3b37267bDoug Thompson
11691318952514d5651c453d89989595a9df3b37267bDoug Thompson	return 0;
11701318952514d5651c453d89989595a9df3b37267bDoug Thompson
1171052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompsonfail:
11721318952514d5651c453d89989595a9df3b37267bDoug Thompson	pci_dev_put(pvt->bridge_ck);
11731318952514d5651c453d89989595a9df3b37267bDoug Thompson	return 1;
11741318952514d5651c453d89989595a9df3b37267bDoug Thompson}
11751318952514d5651c453d89989595a9df3b37267bDoug Thompson
117694ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser/* Setup system bus parity mask register.
117794ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser * Sysbus parity supported on:
11788de5c1a165be5624a1003ce17877299e04b2afd6Konstantin Olifer * e7320/e7520/e7525 + Xeon
117994ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser */
118094ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyserstatic void e752x_init_sysbus_parity_mask(struct e752x_pvt *pvt)
118194ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser{
118294ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser	char *cpu_id = cpu_data(0).x86_model_id;
118394ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser	struct pci_dev *dev = pvt->dev_d0f1;
118494ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser	int enable = 1;
118594ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser
118698a1708de1bfa5fe1c490febba850d6043d3c7faMartin Olsson	/* Allow module parameter override, else see if CPU supports parity */
118794ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser	if (sysbus_parity != -1) {
118894ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser		enable = sysbus_parity;
11898de5c1a165be5624a1003ce17877299e04b2afd6Konstantin Olifer	} else if (cpu_id[0] && !strstr(cpu_id, "Xeon")) {
119094ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser		e752x_printk(KERN_INFO, "System Bus Parity not "
119194ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser			     "supported by CPU, disabling\n");
119294ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser		enable = 0;
119394ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser	}
119494ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser
119594ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser	if (enable)
119694ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser		pci_write_config_word(dev, E752X_SYSBUS_ERRMASK, 0x0000);
119794ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser	else
119894ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser		pci_write_config_word(dev, E752X_SYSBUS_ERRMASK, 0x0309);
119994ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser}
120094ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser
12011318952514d5651c453d89989595a9df3b37267bDoug Thompsonstatic void e752x_init_error_reporting_regs(struct e752x_pvt *pvt)
12021318952514d5651c453d89989595a9df3b37267bDoug Thompson{
12031318952514d5651c453d89989595a9df3b37267bDoug Thompson	struct pci_dev *dev;
12041318952514d5651c453d89989595a9df3b37267bDoug Thompson
12051318952514d5651c453d89989595a9df3b37267bDoug Thompson	dev = pvt->dev_d0f1;
12061318952514d5651c453d89989595a9df3b37267bDoug Thompson	/* Turn off error disable & SMI in case the BIOS turned it on */
12075135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	if (pvt->dev_info->err_dev == PCI_DEVICE_ID_INTEL_3100_1_ERR) {
12085135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		pci_write_config_dword(dev, I3100_NSI_EMASK, 0);
12095135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		pci_write_config_dword(dev, I3100_NSI_SMICMD, 0);
12105135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	} else {
12115135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		pci_write_config_byte(dev, E752X_HI_ERRMASK, 0x00);
12125135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		pci_write_config_byte(dev, E752X_HI_SMICMD, 0x00);
12135135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	}
121494ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser
121594ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser	e752x_init_sysbus_parity_mask(pvt);
121694ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser
12171318952514d5651c453d89989595a9df3b37267bDoug Thompson	pci_write_config_word(dev, E752X_SYSBUS_SMICMD, 0x00);
12181318952514d5651c453d89989595a9df3b37267bDoug Thompson	pci_write_config_byte(dev, E752X_BUF_ERRMASK, 0x00);
12191318952514d5651c453d89989595a9df3b37267bDoug Thompson	pci_write_config_byte(dev, E752X_BUF_SMICMD, 0x00);
12201318952514d5651c453d89989595a9df3b37267bDoug Thompson	pci_write_config_byte(dev, E752X_DRAM_ERRMASK, 0x00);
12211318952514d5651c453d89989595a9df3b37267bDoug Thompson	pci_write_config_byte(dev, E752X_DRAM_SMICMD, 0x00);
12221318952514d5651c453d89989595a9df3b37267bDoug Thompson}
12231318952514d5651c453d89989595a9df3b37267bDoug Thompson
12241318952514d5651c453d89989595a9df3b37267bDoug Thompsonstatic int e752x_probe1(struct pci_dev *pdev, int dev_idx)
12251318952514d5651c453d89989595a9df3b37267bDoug Thompson{
12263847bccce80c8a01d7adbad9961564252207302aDave Peterson	u16 pci_data;
1227806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u8 stat8;
12281318952514d5651c453d89989595a9df3b37267bDoug Thompson	struct mem_ctl_info *mci;
12291318952514d5651c453d89989595a9df3b37267bDoug Thompson	struct e752x_pvt *pvt;
1230806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	u16 ddrcsr;
1231203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	int drc_chan;		/* Number of channels 0=1chan,1=2chan */
1232749ede57443b2a7ede2db105145f21047efcea6aDave Peterson	struct e752x_error_info discard;
1233806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
1234537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson	debugf0("%s(): mci\n", __func__);
1235806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	debugf0("Starting Probe1\n");
1236806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
123796941026a51e9cb8c2d2be7499301b7fcd9ee225mark gross	/* check to see if device 0 function 1 is enabled; if it isn't, we
123896941026a51e9cb8c2d2be7499301b7fcd9ee225mark gross	 * assume the BIOS has reserved it for a reason and is expecting
123996941026a51e9cb8c2d2be7499301b7fcd9ee225mark gross	 * exclusive access, we take care not to violate that assumption and
124096941026a51e9cb8c2d2be7499301b7fcd9ee225mark gross	 * fail the probe. */
1241806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	pci_read_config_byte(pdev, E752X_DEVPRES1, &stat8);
124296941026a51e9cb8c2d2be7499301b7fcd9ee225mark gross	if (!force_function_unhide && !(stat8 & (1 << 5))) {
124396941026a51e9cb8c2d2be7499301b7fcd9ee225mark gross		printk(KERN_INFO "Contact your BIOS vendor to see if the "
1244052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			"E752x error registers can be safely un-hidden\n");
1245f9b5a5d193c3f0bc2a8331d95e0e74d76eb8ee2cAristeu Rozanski		return -ENODEV;
124696941026a51e9cb8c2d2be7499301b7fcd9ee225mark gross	}
1247806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	stat8 |= (1 << 5);
1248806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	pci_write_config_byte(pdev, E752X_DEVPRES1, stat8);
1249806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
1250806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	pci_read_config_word(pdev, E752X_DDRCSR, &ddrcsr);
1251806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	/* FIXME: should check >>12 or 0xf, true for all? */
1252806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	/* Dual channel = 1, Single channel = 0 */
12531318952514d5651c453d89989595a9df3b37267bDoug Thompson	drc_chan = dual_channel_active(ddrcsr);
1254806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
1255b8f6f9755248026f21282e25cac49a1af698056cDoug Thompson	mci = edac_mc_alloc(sizeof(*pvt), E752X_NR_CSROWS, drc_chan + 1, 0);
1256806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
1257806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	if (mci == NULL) {
12581318952514d5651c453d89989595a9df3b37267bDoug Thompson		return -ENOMEM;
1259806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	}
1260806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
1261537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson	debugf3("%s(): init mci\n", __func__);
1262806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	mci->mtype_cap = MEM_FLAG_RDDR;
12635135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	/* 3100 IMCH supports SECDEC only */
12645135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	mci->edac_ctl_cap = (dev_idx == I3100) ? EDAC_FLAG_SECDED :
12655135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		(EDAC_FLAG_NONE | EDAC_FLAG_SECDED | EDAC_FLAG_S4ECD4ED);
1266806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	/* FIXME - what if different memory types are in different csrows? */
1267680cbbbb0e336b04b74be48b8ddd870537f1e226Dave Peterson	mci->mod_name = EDAC_MOD_STR;
126837f04581abac20444e5b7106c1e1f28bec5b989cDoug Thompson	mci->mod_ver = E752X_REVISION;
126937f04581abac20444e5b7106c1e1f28bec5b989cDoug Thompson	mci->dev = &pdev->dev;
1270806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
1271537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson	debugf3("%s(): init pvt\n", __func__);
1272203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	pvt = (struct e752x_pvt *)mci->pvt_info;
1273806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	pvt->dev_info = &e752x_devs[dev_idx];
12741318952514d5651c453d89989595a9df3b37267bDoug Thompson	pvt->mc_symmetric = ((ddrcsr & 0x10) != 0);
1275e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
12761318952514d5651c453d89989595a9df3b37267bDoug Thompson	if (e752x_get_devs(pdev, dev_idx, pvt)) {
12771318952514d5651c453d89989595a9df3b37267bDoug Thompson		edac_mc_free(mci);
12781318952514d5651c453d89989595a9df3b37267bDoug Thompson		return -ENODEV;
1279806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	}
1280806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
1281537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson	debugf3("%s(): more mci init\n", __func__);
1282806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	mci->ctl_name = pvt->dev_info->ctl_name;
1283c4192705fec85219086231a1c0fa61e8776e2c3bDave Jiang	mci->dev_name = pci_name(pdev);
1284806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	mci->edac_check = e752x_check;
1285806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	mci->ctl_page_to_phys = ctl_page_to_phys;
12868004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	mci->set_sdram_scrub_rate = set_sdram_scrub_rate;
12878004fd2ad6042ae24d3913cf5089909781db3a25Peter Tyser	mci->get_sdram_scrub_rate = get_sdram_scrub_rate;
1288806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
12897297c2617f6465d7862e156d4db5d812744280f1Mark Grondona	/* set the map type.  1 = normal, 0 = reversed
12907297c2617f6465d7862e156d4db5d812744280f1Mark Grondona	 * Must be set before e752x_init_csrows in case csrow mapping
12917297c2617f6465d7862e156d4db5d812744280f1Mark Grondona	 * is reversed.
12927297c2617f6465d7862e156d4db5d812744280f1Mark Grondona	 */
129337f04581abac20444e5b7106c1e1f28bec5b989cDoug Thompson	pci_read_config_byte(pdev, E752X_DRM, &stat8);
1294806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	pvt->map_type = ((stat8 & 0x0f) > ((stat8 >> 4) & 0x0f));
1295806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
12967297c2617f6465d7862e156d4db5d812744280f1Mark Grondona	e752x_init_csrows(mci, pdev, ddrcsr);
12977297c2617f6465d7862e156d4db5d812744280f1Mark Grondona	e752x_init_mem_map_table(pdev, pvt);
12987297c2617f6465d7862e156d4db5d812744280f1Mark Grondona
12995135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	if (dev_idx == I3100)
13005135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		mci->edac_cap = EDAC_FLAG_SECDED; /* the only mode supported */
13015135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	else
13025135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov		mci->edac_cap |= EDAC_FLAG_NONE;
1303537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson	debugf3("%s(): tolm, remapbase, remaplimit\n", __func__);
1304e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
1305806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	/* load the top of low memory, remap base, and remap limit vars */
130637f04581abac20444e5b7106c1e1f28bec5b989cDoug Thompson	pci_read_config_word(pdev, E752X_TOLM, &pci_data);
1307806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	pvt->tolm = ((u32) pci_data) << 4;
130837f04581abac20444e5b7106c1e1f28bec5b989cDoug Thompson	pci_read_config_word(pdev, E752X_REMAPBASE, &pci_data);
1309806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	pvt->remapbase = ((u32) pci_data) << 14;
131037f04581abac20444e5b7106c1e1f28bec5b989cDoug Thompson	pci_read_config_word(pdev, E752X_REMAPLIMIT, &pci_data);
1311806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	pvt->remaplimit = ((u32) pci_data) << 14;
1312537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson	e752x_printk(KERN_INFO,
1313052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			"tolm = %x, remapbase = %x, remaplimit = %x\n",
1314052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			pvt->tolm, pvt->remapbase, pvt->remaplimit);
1315806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
13162d7bbb91c8df26c60d223205a087507430024177Doug Thompson	/* Here we assume that we will never see multiple instances of this
13172d7bbb91c8df26c60d223205a087507430024177Doug Thompson	 * type of memory controller.  The ID is therefore hardcoded to 0.
13182d7bbb91c8df26c60d223205a087507430024177Doug Thompson	 */
1319b8f6f9755248026f21282e25cac49a1af698056cDoug Thompson	if (edac_mc_add_mc(mci)) {
1320537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson		debugf3("%s(): failed edac_mc_add_mc()\n", __func__);
1321806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		goto fail;
1322806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	}
1323806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
13241318952514d5651c453d89989595a9df3b37267bDoug Thompson	e752x_init_error_reporting_regs(pvt);
1325203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	e752x_get_error_info(mci, &discard);	/* clear other MCH errors */
1326806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
132791b99041c1d577ded1da599ddc28cec2e07253cfDave Jiang	/* allocating generic PCI control info */
132891b99041c1d577ded1da599ddc28cec2e07253cfDave Jiang	e752x_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR);
132991b99041c1d577ded1da599ddc28cec2e07253cfDave Jiang	if (!e752x_pci) {
133091b99041c1d577ded1da599ddc28cec2e07253cfDave Jiang		printk(KERN_WARNING
1331052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			"%s(): Unable to create PCI control\n", __func__);
133291b99041c1d577ded1da599ddc28cec2e07253cfDave Jiang		printk(KERN_WARNING
1333052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			"%s(): PCI error report via EDAC not setup\n",
1334052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson			__func__);
133591b99041c1d577ded1da599ddc28cec2e07253cfDave Jiang	}
133691b99041c1d577ded1da599ddc28cec2e07253cfDave Jiang
1337806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	/* get this far and it's successful */
1338537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson	debugf3("%s(): success\n", __func__);
1339806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	return 0;
1340806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
1341052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompsonfail:
13421318952514d5651c453d89989595a9df3b37267bDoug Thompson	pci_dev_put(pvt->dev_d0f0);
13431318952514d5651c453d89989595a9df3b37267bDoug Thompson	pci_dev_put(pvt->dev_d0f1);
13441318952514d5651c453d89989595a9df3b37267bDoug Thompson	pci_dev_put(pvt->bridge_ck);
13451318952514d5651c453d89989595a9df3b37267bDoug Thompson	edac_mc_free(mci);
1346e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
13471318952514d5651c453d89989595a9df3b37267bDoug Thompson	return -ENODEV;
1348806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
1349806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
1350806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox/* returns count (>= 0), or negative on error */
1351806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstatic int __devinit e752x_init_one(struct pci_dev *pdev,
1352052dfb45ccb5ea354a426b52556bcfee75b9d2f5Douglas Thompson				const struct pci_device_id *ent)
1353806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
1354537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson	debugf0("%s()\n", __func__);
1355806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
1356806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	/* wake up and enable device */
1357203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	if (pci_enable_device(pdev) < 0)
1358806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		return -EIO;
1359e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson
1360806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	return e752x_probe1(pdev, ent->driver_data);
1361806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
1362806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
1363806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstatic void __devexit e752x_remove_one(struct pci_dev *pdev)
1364806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
1365806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	struct mem_ctl_info *mci;
1366806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	struct e752x_pvt *pvt;
1367806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
1368537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson	debugf0("%s()\n", __func__);
1369806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
137091b99041c1d577ded1da599ddc28cec2e07253cfDave Jiang	if (e752x_pci)
137191b99041c1d577ded1da599ddc28cec2e07253cfDave Jiang		edac_pci_release_generic_ctl(e752x_pci);
137291b99041c1d577ded1da599ddc28cec2e07253cfDave Jiang
137337f04581abac20444e5b7106c1e1f28bec5b989cDoug Thompson	if ((mci = edac_mc_del_mc(&pdev->dev)) == NULL)
1374806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox		return;
1375806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
1376203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	pvt = (struct e752x_pvt *)mci->pvt_info;
1377806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	pci_dev_put(pvt->dev_d0f0);
1378806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	pci_dev_put(pvt->dev_d0f1);
1379806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	pci_dev_put(pvt->bridge_ck);
1380806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	edac_mc_free(mci);
1381806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
1382806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
138336c46f31df910b092aaaed27c7c616bb8e2302a1Lionel Debrouxstatic DEFINE_PCI_DEVICE_TABLE(e752x_pci_tbl) = {
1384e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson	{
1385203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	 PCI_VEND_DEV(INTEL, 7520_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
1386203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	 E7520},
1387e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson	{
1388203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	 PCI_VEND_DEV(INTEL, 7525_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
1389203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	 E7525},
1390e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson	{
1391203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	 PCI_VEND_DEV(INTEL, 7320_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
1392203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	 E7320},
1393e7ecd8910293564d357dbaf18eb179e06fa35fd0Dave Peterson	{
13945135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	 PCI_VEND_DEV(INTEL, 3100_0), PCI_ANY_ID, PCI_ANY_ID, 0, 0,
13955135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	 I3100},
13965135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei Konovalov	{
1397203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	 0,
1398203333cbbaae3941504c2b6e92850783bf361b6fDave Jiang	 }			/* 0 terminated list. */
1399806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox};
1400806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
1401806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan CoxMODULE_DEVICE_TABLE(pci, e752x_pci_tbl);
1402806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
1403806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstatic struct pci_driver e752x_driver = {
1404680cbbbb0e336b04b74be48b8ddd870537f1e226Dave Peterson	.name = EDAC_MOD_STR,
14050d38b049fe8df77c8e9dc48d0fd84555739fbb1aRandy Dunlap	.probe = e752x_init_one,
14060d38b049fe8df77c8e9dc48d0fd84555739fbb1aRandy Dunlap	.remove = __devexit_p(e752x_remove_one),
14070d38b049fe8df77c8e9dc48d0fd84555739fbb1aRandy Dunlap	.id_table = e752x_pci_tbl,
1408806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox};
1409806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
1410da9bb1d27b21cb24cbb6a2efb5d3c464d357a01eAlan Coxstatic int __init e752x_init(void)
1411806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
1412806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	int pci_rc;
1413806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
1414537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson	debugf3("%s()\n", __func__);
1415c3c52bce6993c6d37af2c2de9b482a7013d646a7Hitoshi Mitake
1416c3c52bce6993c6d37af2c2de9b482a7013d646a7Hitoshi Mitake       /* Ensure that the OPSTATE is set correctly for POLL or NMI */
1417c3c52bce6993c6d37af2c2de9b482a7013d646a7Hitoshi Mitake       opstate_init();
1418c3c52bce6993c6d37af2c2de9b482a7013d646a7Hitoshi Mitake
1419806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	pci_rc = pci_register_driver(&e752x_driver);
1420806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	return (pci_rc < 0) ? pci_rc : 0;
1421806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
1422806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
1423806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxstatic void __exit e752x_exit(void)
1424806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox{
1425537fba28928c01b7db1580627450691a4bb0b9b3Dave Peterson	debugf3("%s()\n", __func__);
1426806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox	pci_unregister_driver(&e752x_driver);
1427806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox}
1428806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
1429806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxmodule_init(e752x_init);
1430806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Coxmodule_exit(e752x_exit);
1431806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan Cox
1432806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan CoxMODULE_LICENSE("GPL");
1433806c35f5057a64d3061ee4e2b1023bf6f6d328e2Alan CoxMODULE_AUTHOR("Linux Networx (http://lnxi.com) Tom Zimmerman\n");
14345135b797c8466eac39dc7fb4ae1fac6e7276377aAndrei KonovalovMODULE_DESCRIPTION("MC support for Intel e752x/3100 memory controllers");
143596941026a51e9cb8c2d2be7499301b7fcd9ee225mark gross
143696941026a51e9cb8c2d2be7499301b7fcd9ee225mark grossmodule_param(force_function_unhide, int, 0444);
143796941026a51e9cb8c2d2be7499301b7fcd9ee225mark grossMODULE_PARM_DESC(force_function_unhide, "if BIOS sets Dev0:Fun1 up as hidden:"
143810d33e9c36827e5371479e55ef4089e000af2638Doug Thompson		 " 1=force unhide and hope BIOS doesn't fight driver for "
143910d33e9c36827e5371479e55ef4089e000af2638Doug Thompson		"Dev0:Fun1 access");
1440c3c52bce6993c6d37af2c2de9b482a7013d646a7Hitoshi Mitake
1441c0d121720220584bba2876b032e58a076b843fa1Dave Jiangmodule_param(edac_op_state, int, 0444);
1442c0d121720220584bba2876b032e58a076b843fa1Dave JiangMODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI");
144394ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser
144494ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tysermodule_param(sysbus_parity, int, 0444);
144594ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter TyserMODULE_PARM_DESC(sysbus_parity, "0=disable system bus parity checking,"
144694ee1cf5a88e12f5cbf8c0c78a6c18d3e043241ePeter Tyser		" 1=enable system bus parity checking, default=auto-detect");
144710d33e9c36827e5371479e55ef4089e000af2638Doug Thompsonmodule_param(report_non_memory_errors, int, 0644);
144810d33e9c36827e5371479e55ef4089e000af2638Doug ThompsonMODULE_PARM_DESC(report_non_memory_errors, "0=disable non-memory error "
144910d33e9c36827e5371479e55ef4089e000af2638Doug Thompson		"reporting, 1=enable non-memory error reporting");
1450