3 * Developed for DENX Software Engineering GmbH.
5 * Author: Pavel Kolesnikov <concord@emcraft.com>
7 * See file CREDITS for list of people who contributed to this
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
26 /* define DEBUG for debugging output (obviously ;-)) */
34 #if defined(CONFIG_POST) && (defined(CONFIG_440EPX) || defined(CONFIG_440GRX))
38 #if CONFIG_POST & CFG_POST_ECC
43 * This test performs the checks ECC facility of memory.
45 #include <asm/processor.h>
50 DECLARE_GLOBAL_DATA_PTR;
52 const static unsigned char syndrome_codes[] = {
53 0xF4, 0XF1, 0XEC ,0XEA, 0XE9, 0XE6, 0XE5, 0XE3,
54 0XDC, 0XDA, 0XD9, 0XD6, 0XD5, 0XD3, 0XCE, 0XCB,
55 0xB5, 0XB0, 0XAD, 0XAB, 0XA8, 0XA7, 0XA4, 0XA2,
56 0X9D, 0X9B, 0X98, 0X97, 0X94, 0X92, 0X8F, 0X8A,
57 0x75, 0x70, 0X6D, 0X6B, 0X68, 0X67, 0X64, 0X62,
58 0X5E, 0X5B, 0X58, 0X57, 0X54, 0X52, 0X4F, 0X4A,
59 0x34, 0x31, 0X2C, 0X2A, 0X29, 0X26, 0X25, 0X23,
60 0X1C, 0X1A, 0X19, 0X16, 0X15, 0X13, 0X0E, 0X0B,
61 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
64 #define ECC_START_ADDR 0x10
65 #define ECC_STOP_ADDR 0x2000
66 #define ECC_PATTERN 0x01010101
67 #define ECC_PATTERN_CORR 0x11010101
68 #define ECC_PATTERN_UNCORR 0xF1010101
70 static int test_ecc_error(void)
73 unsigned long hdata, ldata, haddr, laddr;
78 mfsdram(DDR0_23, value);
80 for (bit = 0; bit < sizeof(syndrome_codes); bit++)
81 if (syndrome_codes[bit] == ((value >> 16) & 0xff))
84 mfsdram(DDR0_00, value);
86 if (value & DDR0_00_INT_STATUS_BIT0) {
87 debug("Bit0. A single access outside the defined PHYSICAL"
88 " memory space detected\n");
89 mfsdram(DDR0_32, laddr);
90 mfsdram(DDR0_33, haddr);
91 debug(" addr = 0x%08x%08x\n", haddr, laddr);
94 if (value & DDR0_00_INT_STATUS_BIT1) {
95 debug("Bit1. Multiple accesses outside the defined PHYSICAL"
96 " memory space detected\n");
99 if (value & DDR0_00_INT_STATUS_BIT2) {
100 debug("Bit2. Single correctable ECC event detected\n");
101 mfsdram(DDR0_38, laddr);
102 mfsdram(DDR0_39, haddr);
103 mfsdram(DDR0_40, ldata);
104 mfsdram(DDR0_41, hdata);
105 debug(" 0x%08x - 0x%08x%08x, bit - %d\n",
106 laddr, hdata, ldata, bit);
109 if (value & DDR0_00_INT_STATUS_BIT3) {
110 debug("Bit3. Multiple correctable ECC events detected\n");
111 mfsdram(DDR0_38, laddr);
112 mfsdram(DDR0_39, haddr);
113 mfsdram(DDR0_40, ldata);
114 mfsdram(DDR0_41, hdata);
115 debug(" 0x%08x - 0x%08x%08x, bit - %d\n",
116 laddr, hdata, ldata, bit);
119 if (value & DDR0_00_INT_STATUS_BIT4) {
120 debug("Bit4. Single uncorrectable ECC event detected\n");
121 mfsdram(DDR0_34, laddr);
122 mfsdram(DDR0_35, haddr);
123 mfsdram(DDR0_36, ldata);
124 mfsdram(DDR0_37, hdata);
125 debug(" 0x%08x - 0x%08x%08x, bit - %d\n",
126 laddr, hdata, ldata, bit);
129 if (value & DDR0_00_INT_STATUS_BIT5) {
130 debug("Bit5. Multiple uncorrectable ECC events detected\n");
131 mfsdram(DDR0_34, laddr);
132 mfsdram(DDR0_35, haddr);
133 mfsdram(DDR0_36, ldata);
134 mfsdram(DDR0_37, hdata);
135 debug(" 0x%08x - 0x%08x%08x, bit - %d\n",
136 laddr, hdata, ldata, bit);
139 if (value & DDR0_00_INT_STATUS_BIT6) {
140 debug("Bit6. DRAM initialization complete\n");
144 /* error status cleared */
145 mfsdram(DDR0_00, value);
146 mtsdram(DDR0_00, value | DDR0_00_INT_ACK_ALL);
151 static int test_ecc(unsigned long ecc_addr)
154 volatile unsigned *const ecc_mem = (volatile unsigned *) ecc_addr;
162 debug("Entering test_ecc(0x%08lX)\n", ecc_addr);
163 out_be32(ecc_mem, ECC_PATTERN);
164 out_be32(ecc_mem + 1, ECC_PATTERN);
166 pret = test_ecc_error();
168 debug("pret: expected 0, got %d\n", pret);
171 /* test for correctable error */
172 /* disconnect from ecc storage */
173 mfsdram(DDR0_22, value);
174 mtsdram(DDR0_22, (value &~ DDR0_22_CTRL_RAW_MASK)
175 | DDR0_22_CTRL_RAW_ECC_DISABLE);
177 /* creating (correctable) single-bit error */
178 out_be32(ecc_mem, ECC_PATTERN_CORR);
181 mfsdram(DDR0_22, value);
182 mtsdram(DDR0_22, (value &~ DDR0_22_CTRL_RAW_MASK)
183 | DDR0_22_CTRL_RAW_ECC_ENABLE);
188 pret = test_ecc_error();
189 /* if read data ok, 1 correctable error must be fixed */
191 debug("pret: expected 3, got %d\n", pret);
194 /* test for uncorrectable error */
195 /* disconnect from ecc storage */
196 mfsdram(DDR0_22, value);
197 mtsdram(DDR0_22, (value &~ DDR0_22_CTRL_RAW_MASK)
198 | DDR0_22_CTRL_RAW_NO_ECC_RAM);
200 /* creating (uncorrectable) multiple-bit error */
201 out_be32(ecc_mem, ECC_PATTERN_UNCORR);
204 mfsdram(DDR0_22, value);
205 mtsdram(DDR0_22, (value &~ DDR0_22_CTRL_RAW_MASK)
206 | DDR0_22_CTRL_RAW_ECC_ENABLE);
211 pret = test_ecc_error();
212 /* info about uncorrectable error must appear */
214 debug("pret: expected 5, got %d\n", pret);
217 /* remove error from SDRAM */
218 out_be32(ecc_mem, ECC_PATTERN);
219 /* clear error caused by read-modify-write */
220 mfsdram(DDR0_00, value);
221 mtsdram(DDR0_00, value | DDR0_00_INT_ACK_ALL);
228 int ecc_post_test (int flags)
237 mfsdram(DDR0_22, value);
238 if (0x3 != DDR0_22_CTRL_RAW_DECODE(value)) {
239 debug("SDRAM ECC not enabled, skipping ECC POST.\n");
244 mfsdram(DDR0_01, value);
245 mtsdram(DDR0_01, (value &~ DDR0_01_INT_MASK_MASK)
246 | DDR0_01_INT_MASK_ALL_OFF);
248 /* clear error status */
249 mfsdram(DDR0_00, value);
250 mtsdram(DDR0_00, value | DDR0_00_INT_ACK_ALL);
252 for (iaddr = ECC_START_ADDR; iaddr <= ECC_STOP_ADDR; iaddr += iaddr) {
253 ret = test_ecc(iaddr);
258 * Clear possible errors resulting from ECC testing.
259 * If not done, then we could get an interrupt later on when
260 * exceptions are enabled.
262 set_mcsr(get_mcsr());
266 #endif /* CONFIG_POST & CFG_POST_ECC */
267 #endif /* defined(CONFIG_POST) && ... */