]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - post/board/lwmon5/fpga.c
Merge branch 'master' of git://www.denx.de/git/u-boot-cfi-flash
[karo-tx-uboot.git] / post / board / lwmon5 / fpga.c
1 /*
2  * (C) Copyright 2008 Dmitry Rakhchev, EmCraft Systems, rda@emcraft.com
3  *
4  * Developed for DENX Software Engineering GmbH
5  *
6  * SPDX-License-Identifier:     GPL-2.0+
7  */
8 #include <common.h>
9
10 /* This test performs testing of FPGA SCRATCH register,
11  * gets FPGA version and run get_ram_size() on FPGA memory
12  */
13
14 #include <post.h>
15 #include <watchdog.h>
16 #include <asm/io.h>
17
18 DECLARE_GLOBAL_DATA_PTR;
19
20 #define FPGA_SCRATCH_REG        0xC4000050
21 #define FPGA_VERSION_REG        0xC4000040
22 #define FPGA_RAM_START          0xC4200000
23 #define FPGA_RAM_END            0xC4203FFF
24 #define FPGA_STAT               0xC400000C
25 #define FPGA_BUFFER             0x00800000
26 #define FPGA_RAM_SIZE           (FPGA_RAM_END - FPGA_RAM_START + 1)
27
28 #if CONFIG_POST & CONFIG_SYS_POST_BSPEC3
29
30 const static unsigned long pattern[] = {
31         0xffffffff,
32         0xaaaaaaaa,
33         0xcccccccc,
34         0xf0f0f0f0,
35         0xff00ff00,
36         0xffff0000,
37         0x0000ffff,
38         0x00ff00ff,
39         0x0f0f0f0f,
40         0x33333333,
41         0x55555555,
42         0x00000000,
43 };
44
45 const static unsigned long otherpattern = 0x01234567;
46
47 static int one_scratch_test(uint value)
48 {
49         uint read_value;
50         int ret = 0;
51
52         out_be32((void *)FPGA_SCRATCH_REG, value);
53         /* read other location (protect against data lines capacity) */
54         ret = in_be16((void *)FPGA_VERSION_REG);
55         /* verify test pattern */
56         read_value = in_be32((void *)FPGA_SCRATCH_REG);
57         if (read_value != value) {
58                 post_log("FPGA SCRATCH test failed write %08X, read %08X\n",
59                          value, read_value);
60                 ret = -1;
61         }
62
63         return ret;
64 }
65
66 static int fpga_post_test1(ulong *start, ulong size, ulong val)
67 {
68         int ret = 0;
69         ulong i = 0;
70         ulong *mem = start;
71         ulong readback;
72
73         for (i = 0; i < size / sizeof(ulong); i++) {
74                 mem[i] = val;
75                 if (i % 1024 == 0)
76                         WATCHDOG_RESET();
77         }
78
79         for (i = 0; i < size / sizeof(ulong); i++) {
80                 readback = mem[i];
81                 if (readback != val) {
82                         post_log("FPGA Memory error at %08x, "
83                                  "wrote %08x, read %08x !\n",
84                                  mem + i, val, readback);
85                         ret = -1;
86                         break;
87                 }
88                 if (i % 1024 == 0)
89                         WATCHDOG_RESET();
90         }
91         return ret;
92 }
93
94 static int fpga_post_test2(ulong *start, ulong size)
95 {
96         int ret = 0;
97         ulong i = 0;
98         ulong *mem = start;
99         ulong readback;
100
101         for (i = 0; i < size / sizeof(ulong); i++) {
102                 mem[i] = 1 << (i % 32);
103                 if (i % 1024 == 0)
104                         WATCHDOG_RESET();
105         }
106
107         for (i = 0; i < size / sizeof(ulong); i++) {
108                 readback = mem[i];
109                 if (readback != 1 << (i % 32)) {
110                         post_log("FPGA Memory error at %08x, "
111                                  "wrote %08x, read %08x !\n",
112                                  mem + i, 1 << (i % 32), readback);
113                         ret = -1;
114                         break;
115                 }
116                 if (i % 1024 == 0)
117                         WATCHDOG_RESET();
118         }
119
120         return ret;
121 }
122
123 static int fpga_post_test3(ulong *start, ulong size)
124 {
125         int ret = 0;
126         ulong i = 0;
127         ulong *mem = start;
128         ulong readback;
129
130         for (i = 0; i < size / sizeof(ulong); i++) {
131                 mem[i] = i;
132                 if (i % 1024 == 0)
133                         WATCHDOG_RESET();
134         }
135
136         for (i = 0; i < size / sizeof(ulong); i++) {
137                 readback = mem[i];
138                 if (readback != i) {
139                         post_log("FPGA Memory error at %08x, "
140                                  "wrote %08x, read %08x !\n",
141                                  mem + i, i, readback);
142                         ret = -1;
143                         break;
144                 }
145                 if (i % 1024 == 0)
146                         WATCHDOG_RESET();
147         }
148
149         return ret;
150 }
151
152 static int fpga_post_test4(ulong *start, ulong size)
153 {
154         int ret = 0;
155         ulong i = 0;
156         ulong *mem = start;
157         ulong readback;
158
159         for (i = 0; i < size / sizeof(ulong); i++) {
160                 mem[i] = ~i;
161                 if (i % 1024 == 0)
162                         WATCHDOG_RESET();
163         }
164
165         for (i = 0; i < size / sizeof(ulong); i++) {
166                 readback = mem[i];
167                 if (readback != ~i) {
168                         post_log("FPGA Memory error at %08x, "
169                                  "wrote %08x, read %08x !\n",
170                                  mem + i, ~i, readback);
171                         ret = -1;
172                         break;
173                 }
174                 if (i % 1024 == 0)
175                         WATCHDOG_RESET();
176         }
177
178         return ret;
179 }
180
181 /* FPGA Memory-pattern-test */
182 static int fpga_mem_test(void)
183 {
184         int ret = 0;
185         ulong* start = (ulong *)FPGA_RAM_START;
186         ulong  size  = FPGA_RAM_SIZE;
187
188         if (ret == 0)
189                 ret = fpga_post_test1(start, size, 0x00000000);
190
191         if (ret == 0)
192                 ret = fpga_post_test1(start, size, 0xffffffff);
193
194         if (ret == 0)
195                 ret = fpga_post_test1(start, size, 0x55555555);
196
197         if (ret == 0)
198                 ret = fpga_post_test1(start, size, 0xaaaaaaaa);
199
200         WATCHDOG_RESET();
201
202         if (ret == 0)
203                 ret = fpga_post_test2(start, size);
204
205         if (ret == 0)
206                 ret = fpga_post_test3(start, size);
207
208         if (ret == 0)
209                 ret = fpga_post_test4(start, size);
210
211         return ret;
212 }
213
214 /* Verify FPGA addresslines */
215 static int fpga_post_addrline(ulong *address, ulong *base, ulong size)
216 {
217         unsigned long *target;
218         unsigned long *end;
219         unsigned long readback;
220         unsigned long xor;
221         int ret = 0;
222
223         end = (ulong *)((ulong)base + size);
224         xor = 0;
225
226         for (xor = sizeof(ulong); xor > 0; xor <<= 1) {
227                 target = (ulong*)((ulong)address ^ xor);
228                 if ((target >= base) && (target < end)) {
229                         *address = ~*target;
230                         readback = *target;
231
232                         if (readback == *address) {
233                                 post_log("Memory (address line) error at %08x"
234                                          "XOR value %08x !\n",
235                                          address, target, xor);
236                                 ret = -1;
237                                 break;
238                         }
239                 }
240         }
241
242         return ret;
243 }
244
245 /* Verify FPGA addresslines */
246 static int fpga_post_dataline(ulong *address)
247 {
248         unsigned long temp32 = 0;
249         int i = 0;
250         int ret = 0;
251
252         for (i = 0; i < ARRAY_SIZE(pattern); i++) {
253                 *address = pattern[i];
254                 /*
255                  * Put a different pattern on the data lines: otherwise they
256                  * may float long enough to read back what we wrote.
257                  */
258                 *(address + 1) = otherpattern;
259                 temp32 = *address;
260
261                 if (temp32 != pattern[i]){
262                         post_log("Memory (date line) error at %08x, "
263                                  "wrote %08x, read %08x !\n",
264                                  address, pattern[i], temp32);
265                         ret = 1;
266                 }
267         }
268
269         return ret;
270 }
271
272 /* Verify FPGA, get version & memory size */
273 int fpga_post_test(int flags)
274 {
275         uint   old_value;
276         uint   version;
277         uint   read_value;
278         int    ret = 0;
279
280         post_log("\n");
281         old_value = in_be32((void *)FPGA_SCRATCH_REG);
282
283         if (one_scratch_test(0x55555555))
284                 ret = 1;
285         if (one_scratch_test(0xAAAAAAAA))
286                 ret = 1;
287
288         out_be32((void *)FPGA_SCRATCH_REG, old_value);
289
290         version = in_be32((void *)FPGA_VERSION_REG);
291         post_log("FPGA version %u.%u\n",
292                  (version >> 8) & 0xFF, version & 0xFF);
293
294         /* Enable write to FPGA RAM */
295         out_be32((void *)FPGA_STAT, in_be32((void *)FPGA_STAT) | 0x1000);
296
297         /* get RAM size */
298         read_value = get_ram_size((void *)CONFIG_SYS_FPGA_BASE_1, FPGA_RAM_SIZE);
299         post_log("FPGA RAM size %d bytes\n", read_value);
300         WATCHDOG_RESET();
301
302         /* copy fpga memory to DDR2 RAM*/
303         memcpy((void *)FPGA_BUFFER,(void *)FPGA_RAM_START, FPGA_RAM_SIZE);
304         WATCHDOG_RESET();
305
306         /* Test datalines */
307         if (fpga_post_dataline((ulong *)FPGA_RAM_START)) {
308                 ret = 1;
309                 goto out;
310         }
311         WATCHDOG_RESET();
312
313         /* Test addresslines */
314         if (fpga_post_addrline((ulong *)FPGA_RAM_START,
315                                (ulong *)FPGA_RAM_START, FPGA_RAM_SIZE)) {
316                 ret = 1;
317                 goto out;
318         }
319         WATCHDOG_RESET();
320         if (fpga_post_addrline((ulong *)FPGA_RAM_END - sizeof(long),
321                                (ulong *)FPGA_RAM_START, FPGA_RAM_SIZE)) {
322                 ret = 1;
323                 goto out;
324         }
325         WATCHDOG_RESET();
326
327         /* Memory Pattern Test */
328         if (fpga_mem_test()) {
329                 ret = 1;
330                 goto out;
331         }
332         WATCHDOG_RESET();
333
334         /* restore memory */
335         memcpy((void *)FPGA_RAM_START,(void *)FPGA_BUFFER, FPGA_RAM_SIZE);
336         WATCHDOG_RESET();
337
338 out:
339         /* Disable write to RAM */
340         out_be32((void *)FPGA_STAT, in_be32((void *)FPGA_STAT) & 0xEFFF);
341         return ret;
342 }
343
344 #endif /* CONFIG_POST & CONFIG_SYS_POST_BSPEC3 */