tizen 2.4 release
[profile/mobile/platform/kernel/u-boot-tm1.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  * See file CREDITS for list of people who contributed to this
7  * project.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22  * MA 02111-1307 USA
23  */
24 #include <common.h>
25
26 /* This test performs testing of FPGA SCRATCH register,
27  * gets FPGA version and run get_ram_size() on FPGA memory
28  */
29
30 #include <post.h>
31 #include <watchdog.h>
32 #include <asm/io.h>
33
34 DECLARE_GLOBAL_DATA_PTR;
35
36 #define FPGA_SCRATCH_REG        0xC4000050
37 #define FPGA_VERSION_REG        0xC4000040
38 #define FPGA_RAM_START          0xC4200000
39 #define FPGA_RAM_END            0xC4203FFF
40 #define FPGA_STAT               0xC400000C
41 #define FPGA_BUFFER             0x00800000
42 #define FPGA_RAM_SIZE           (FPGA_RAM_END - FPGA_RAM_START + 1)
43
44 #if CONFIG_POST & CONFIG_SYS_POST_BSPEC3
45
46 const static unsigned long pattern[] = {
47         0xffffffff,
48         0xaaaaaaaa,
49         0xcccccccc,
50         0xf0f0f0f0,
51         0xff00ff00,
52         0xffff0000,
53         0x0000ffff,
54         0x00ff00ff,
55         0x0f0f0f0f,
56         0x33333333,
57         0x55555555,
58         0x00000000,
59 };
60
61 const static unsigned long otherpattern = 0x01234567;
62
63 static int one_scratch_test(uint value)
64 {
65         uint read_value;
66         int ret = 0;
67
68         out_be32((void *)FPGA_SCRATCH_REG, value);
69         /* read other location (protect against data lines capacity) */
70         ret = in_be16((void *)FPGA_VERSION_REG);
71         /* verify test pattern */
72         read_value = in_be32((void *)FPGA_SCRATCH_REG);
73         if (read_value != value) {
74                 post_log("FPGA SCRATCH test failed write %08X, read %08X\n",
75                          value, read_value);
76                 ret = -1;
77         }
78
79         return ret;
80 }
81
82 static int fpga_post_test1(ulong *start, ulong size, ulong val)
83 {
84         int ret = 0;
85         ulong i = 0;
86         ulong *mem = start;
87         ulong readback;
88
89         for (i = 0; i < size / sizeof(ulong); i++) {
90                 mem[i] = val;
91                 if (i % 1024 == 0)
92                         WATCHDOG_RESET();
93         }
94
95         for (i = 0; i < size / sizeof(ulong); i++) {
96                 readback = mem[i];
97                 if (readback != val) {
98                         post_log("FPGA Memory error at %08x, "
99                                  "wrote %08x, read %08x !\n",
100                                  mem + i, val, readback);
101                         ret = -1;
102                         break;
103                 }
104                 if (i % 1024 == 0)
105                         WATCHDOG_RESET();
106         }
107         return ret;
108 }
109
110 static int fpga_post_test2(ulong *start, ulong size)
111 {
112         int ret = 0;
113         ulong i = 0;
114         ulong *mem = start;
115         ulong readback;
116
117         for (i = 0; i < size / sizeof(ulong); i++) {
118                 mem[i] = 1 << (i % 32);
119                 if (i % 1024 == 0)
120                         WATCHDOG_RESET();
121         }
122
123         for (i = 0; i < size / sizeof(ulong); i++) {
124                 readback = mem[i];
125                 if (readback != 1 << (i % 32)) {
126                         post_log("FPGA Memory error at %08x, "
127                                  "wrote %08x, read %08x !\n",
128                                  mem + i, 1 << (i % 32), readback);
129                         ret = -1;
130                         break;
131                 }
132                 if (i % 1024 == 0)
133                         WATCHDOG_RESET();
134         }
135
136         return ret;
137 }
138
139 static int fpga_post_test3(ulong *start, ulong size)
140 {
141         int ret = 0;
142         ulong i = 0;
143         ulong *mem = start;
144         ulong readback;
145
146         for (i = 0; i < size / sizeof(ulong); i++) {
147                 mem[i] = i;
148                 if (i % 1024 == 0)
149                         WATCHDOG_RESET();
150         }
151
152         for (i = 0; i < size / sizeof(ulong); i++) {
153                 readback = mem[i];
154                 if (readback != i) {
155                         post_log("FPGA Memory error at %08x, "
156                                  "wrote %08x, read %08x !\n",
157                                  mem + i, i, readback);
158                         ret = -1;
159                         break;
160                 }
161                 if (i % 1024 == 0)
162                         WATCHDOG_RESET();
163         }
164
165         return ret;
166 }
167
168 static int fpga_post_test4(ulong *start, ulong size)
169 {
170         int ret = 0;
171         ulong i = 0;
172         ulong *mem = start;
173         ulong readback;
174
175         for (i = 0; i < size / sizeof(ulong); i++) {
176                 mem[i] = ~i;
177                 if (i % 1024 == 0)
178                         WATCHDOG_RESET();
179         }
180
181         for (i = 0; i < size / sizeof(ulong); i++) {
182                 readback = mem[i];
183                 if (readback != ~i) {
184                         post_log("FPGA Memory error at %08x, "
185                                  "wrote %08x, read %08x !\n",
186                                  mem + i, ~i, readback);
187                         ret = -1;
188                         break;
189                 }
190                 if (i % 1024 == 0)
191                         WATCHDOG_RESET();
192         }
193
194         return ret;
195 }
196
197 /* FPGA Memory-pattern-test */
198 static int fpga_mem_test(void)
199 {
200         int ret = 0;
201         ulong* start = (ulong *)FPGA_RAM_START;
202         ulong  size  = FPGA_RAM_SIZE;
203
204         if (ret == 0)
205                 ret = fpga_post_test1(start, size, 0x00000000);
206
207         if (ret == 0)
208                 ret = fpga_post_test1(start, size, 0xffffffff);
209
210         if (ret == 0)
211                 ret = fpga_post_test1(start, size, 0x55555555);
212
213         if (ret == 0)
214                 ret = fpga_post_test1(start, size, 0xaaaaaaaa);
215
216         WATCHDOG_RESET();
217
218         if (ret == 0)
219                 ret = fpga_post_test2(start, size);
220
221         if (ret == 0)
222                 ret = fpga_post_test3(start, size);
223
224         if (ret == 0)
225                 ret = fpga_post_test4(start, size);
226
227         return ret;
228 }
229
230 /* Verify FPGA addresslines */
231 static int fpga_post_addrline(ulong *address, ulong *base, ulong size)
232 {
233         unsigned long *target;
234         unsigned long *end;
235         unsigned long readback;
236         unsigned long xor;
237         int ret = 0;
238
239         end = (ulong *)((ulong)base + size);
240         xor = 0;
241
242         for (xor = sizeof(ulong); xor > 0; xor <<= 1) {
243                 target = (ulong*)((ulong)address ^ xor);
244                 if ((target >= base) && (target < end)) {
245                         *address = ~*target;
246                         readback = *target;
247
248                         if (readback == *address) {
249                                 post_log("Memory (address line) error at %08x"
250                                          "XOR value %08x !\n",
251                                          address, target, xor);
252                                 ret = -1;
253                                 break;
254                         }
255                 }
256         }
257
258         return ret;
259 }
260
261 /* Verify FPGA addresslines */
262 static int fpga_post_dataline(ulong *address)
263 {
264         unsigned long temp32 = 0;
265         int i = 0;
266         int ret = 0;
267
268         for (i = 0; i < ARRAY_SIZE(pattern); i++) {
269                 *address = pattern[i];
270                 /*
271                  * Put a different pattern on the data lines: otherwise they
272                  * may float long enough to read back what we wrote.
273                  */
274                 *(address + 1) = otherpattern;
275                 temp32 = *address;
276
277                 if (temp32 != pattern[i]){
278                         post_log("Memory (date line) error at %08x, "
279                                  "wrote %08x, read %08x !\n",
280                                  address, pattern[i], temp32);
281                         ret = 1;
282                 }
283         }
284
285         return ret;
286 }
287
288 /* Verify FPGA, get version & memory size */
289 int fpga_post_test(int flags)
290 {
291         uint   old_value;
292         uint   version;
293         uint   read_value;
294         int    ret = 0;
295
296         post_log("\n");
297         old_value = in_be32((void *)FPGA_SCRATCH_REG);
298
299         if (one_scratch_test(0x55555555))
300                 ret = 1;
301         if (one_scratch_test(0xAAAAAAAA))
302                 ret = 1;
303
304         out_be32((void *)FPGA_SCRATCH_REG, old_value);
305
306         version = in_be32((void *)FPGA_VERSION_REG);
307         post_log("FPGA version %u.%u\n",
308                  (version >> 8) & 0xFF, version & 0xFF);
309
310         /* Enable write to FPGA RAM */
311         out_be32((void *)FPGA_STAT, in_be32((void *)FPGA_STAT) | 0x1000);
312
313         /* get RAM size */
314         read_value = get_ram_size((void *)CONFIG_SYS_FPGA_BASE_1, FPGA_RAM_SIZE);
315         post_log("FPGA RAM size %d bytes\n", read_value);
316         WATCHDOG_RESET();
317
318         /* copy fpga memory to DDR2 RAM*/
319         memcpy((void *)FPGA_BUFFER,(void *)FPGA_RAM_START, FPGA_RAM_SIZE);
320         WATCHDOG_RESET();
321
322         /* Test datalines */
323         if (fpga_post_dataline((ulong *)FPGA_RAM_START)) {
324                 ret = 1;
325                 goto out;
326         }
327         WATCHDOG_RESET();
328
329         /* Test addresslines */
330         if (fpga_post_addrline((ulong *)FPGA_RAM_START,
331                                (ulong *)FPGA_RAM_START, FPGA_RAM_SIZE)) {
332                 ret = 1;
333                 goto out;
334         }
335         WATCHDOG_RESET();
336         if (fpga_post_addrline((ulong *)FPGA_RAM_END - sizeof(long),
337                                (ulong *)FPGA_RAM_START, FPGA_RAM_SIZE)) {
338                 ret = 1;
339                 goto out;
340         }
341         WATCHDOG_RESET();
342
343         /* Memory Pattern Test */
344         if (fpga_mem_test()) {
345                 ret = 1;
346                 goto out;
347         }
348         WATCHDOG_RESET();
349
350         /* restore memory */
351         memcpy((void *)FPGA_RAM_START,(void *)FPGA_BUFFER, FPGA_RAM_SIZE);
352         WATCHDOG_RESET();
353
354 out:
355         /* Disable write to RAM */
356         out_be32((void *)FPGA_STAT, in_be32((void *)FPGA_STAT) & 0xEFFF);
357         return ret;
358 }
359
360 #endif /* CONFIG_POST & CONFIG_SYS_POST_BSPEC3 */