Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / board / esd / ar405 / ar405.c
1 /*
2  * (C) Copyright 2001-2004
3  * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <common.h>
9 #include "ar405.h"
10 #include <asm/processor.h>
11 #include <asm/io.h>
12 #include <command.h>
13
14 DECLARE_GLOBAL_DATA_PTR;
15
16 extern void lxt971_no_sleep(void);
17
18 /* ------------------------------------------------------------------------- */
19
20 #if 0
21 #define FPGA_DEBUG
22 #endif
23
24 /* fpga configuration data - generated by bin2cc */
25 const unsigned char fpgadata[] = {
26 #include "fpgadata.c"
27 };
28
29 const unsigned char fpgadata_xl30[] = {
30 #include "fpgadata_xl30.c"
31 };
32
33 /*
34  * include common fpga code (for esd boards)
35  */
36 #include "../common/fpga.c"
37
38
39 int board_early_init_f (void)
40 {
41         int index, len, i;
42         int status;
43
44 #ifdef FPGA_DEBUG
45         /* set up serial port with default baudrate */
46         (void) get_clocks ();
47         gd->baudrate = CONFIG_BAUDRATE;
48         serial_init ();
49         console_init_f ();
50 #endif
51
52         /*
53          * Boot onboard FPGA
54          */
55         /* first try 40er image */
56         gd->board_type = 40;
57         status = fpga_boot ((unsigned char *) fpgadata, sizeof (fpgadata));
58         if (status != 0) {
59                 /* try xl30er image */
60                 gd->board_type = 30;
61                 status = fpga_boot ((unsigned char *) fpgadata_xl30, sizeof (fpgadata_xl30));
62                 if (status != 0) {
63                         /* booting FPGA failed */
64 #ifndef FPGA_DEBUG
65                         /* set up serial port with default baudrate */
66                         (void) get_clocks ();
67                         gd->baudrate = CONFIG_BAUDRATE;
68                         serial_init ();
69                         console_init_f ();
70 #endif
71                         printf ("\nFPGA: Booting failed ");
72                         switch (status) {
73                         case ERROR_FPGA_PRG_INIT_LOW:
74                                 printf ("(Timeout: INIT not low after asserting PROGRAM*)\n ");
75                                 break;
76                         case ERROR_FPGA_PRG_INIT_HIGH:
77                                 printf ("(Timeout: INIT not high after deasserting PROGRAM*)\n ");
78                                 break;
79                         case ERROR_FPGA_PRG_DONE:
80                                 printf ("(Timeout: DONE not high after programming FPGA)\n ");
81                                 break;
82                         }
83
84                         /* display infos on fpgaimage */
85                         index = 15;
86                         for (i = 0; i < 4; i++) {
87                                 len = fpgadata[index];
88                                 printf ("FPGA: %s\n", &(fpgadata[index + 1]));
89                                 index += len + 3;
90                         }
91                         putc ('\n');
92                         /* delayed reboot */
93                         for (i = 20; i > 0; i--) {
94                                 printf ("Rebooting in %2d seconds \r", i);
95                                 for (index = 0; index < 1000; index++)
96                                         udelay (1000);
97                         }
98                         putc ('\n');
99                         do_reset (NULL, 0, 0, NULL);
100                 }
101         }
102
103         /*
104          * IRQ 0-15  405GP internally generated; active high; level sensitive
105          * IRQ 16    405GP internally generated; active low; level sensitive
106          * IRQ 17-24 RESERVED
107          * IRQ 25 (EXT IRQ 0) CAN0; active low; level sensitive
108          * IRQ 26 (EXT IRQ 1) CAN1; active low; level sensitive
109          * IRQ 27 (EXT IRQ 2) PCI SLOT 0; active low; level sensitive
110          * IRQ 28 (EXT IRQ 3) PCI SLOT 1; active low; level sensitive
111          * IRQ 29 (EXT IRQ 4) PCI SLOT 2; active low; level sensitive
112          * IRQ 30 (EXT IRQ 5) PCI SLOT 3; active low; level sensitive
113          * IRQ 31 (EXT IRQ 6) COMPACT FLASH; active high; level sensitive
114          */
115         mtdcr (UIC0SR, 0xFFFFFFFF);     /* clear all ints */
116         mtdcr (UIC0ER, 0x00000000);     /* disable all ints */
117         mtdcr (UIC0CR, 0x00000000);     /* set all to be non-critical */
118         mtdcr (UIC0PR, 0xFFFFFF81);     /* set int polarities */
119         mtdcr (UIC0TR, 0x10000000);     /* set int trigger levels */
120         mtdcr (UIC0VCR, 0x00000001);    /* set vect base=0,INT0 highest priority */
121         mtdcr (UIC0SR, 0xFFFFFFFF);     /* clear all ints */
122
123         out_be16((void *)0xf03000ec, 0x0fff); /* enable interrupts in fpga */
124
125         return 0;
126 }
127
128 /*
129  * Check Board Identity:
130  */
131 int checkboard (void)
132 {
133         int index;
134         int len;
135         char str[64];
136         int i = getenv_f("serial#", str, sizeof (str));
137         const unsigned char *fpga;
138
139         puts ("Board: ");
140
141         if (i == -1) {
142                 puts ("### No HW ID - assuming AR405");
143         } else {
144                 puts(str);
145         }
146
147         puts ("\nFPGA:  ");
148
149         /* display infos on fpgaimage */
150         if (gd->board_type == 30) {
151                 fpga = fpgadata_xl30;
152         } else {
153                 fpga = fpgadata;
154         }
155         index = 15;
156         for (i = 0; i < 4; i++) {
157                 len = fpga[index];
158                 printf ("%s ", &(fpga[index + 1]));
159                 index += len + 3;
160         }
161
162         putc ('\n');
163
164         /*
165          * Disable sleep mode in LXT971
166          */
167         lxt971_no_sleep();
168
169         return 0;
170 }
171
172
173 #if 1 /* test-only: some internal test routines... */
174 #define DIGEN   ((void *)0xf03000b4) /* u8 */
175 #define DIGOUT  ((void *)0xf03000b0) /* u16 */
176 #define DIGIN   ((void *)0xf03000a0) /* u16 */
177
178 /*
179  * Some test routines
180  */
181 int do_digtest(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
182 {
183         int i;
184         int k;
185         int start;
186         int end;
187
188         if (argc != 3) {
189                 puts("Usage: digtest n_start n_end (digtest 0 7)\n");
190                 return 0;
191         }
192
193         start = simple_strtol (argv[1], NULL, 10);
194         end = simple_strtol (argv[2], NULL, 10);
195
196         /*
197          * Enable digital outputs
198          */
199         out_8(DIGEN, 0x08);
200
201         printf("\nStarting digital In-/Out Test from I/O %d to %d (Cntrl-C to abort)...\n",
202                start, end);
203
204         /*
205          * Set outputs one by one
206          */
207         for (;;) {
208                 for (i=start; i<=end; i++) {
209                         out_be16(DIGOUT, 0x0001 << i);
210                         for (k=0; k<200; k++)
211                                 udelay(1000);
212
213                         if (in_be16(DIGIN) != (0x0001 << i)) {
214                                 printf("ERROR: OUT=0x%04X, IN=0x%04X\n",
215                                        0x0001 << i, in_be16(DIGIN));
216                                 return 0;
217                         }
218
219                         /* Abort if ctrl-c was pressed */
220                         if (ctrlc()) {
221                                 puts("\nAbort\n");
222                                 return 0;
223                         }
224                 }
225         }
226
227         return 0;
228 }
229 U_BOOT_CMD(
230         digtest,        3,      1,      do_digtest,
231         "Test digital in-/output",
232         ""
233 );
234
235 #define ERROR_DELTA     256
236
237 struct io {
238         short val;
239         short dummy;
240 };
241
242 int do_anatest(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
243 {
244         short val;
245         int i;
246         int volt;
247         struct io *out;
248         struct io *in;
249
250         out = (struct io *)0xf0300090;
251         in = (struct io *)0xf0300000;
252
253         i = simple_strtol (argv[1], NULL, 10);
254
255         volt = 0;
256         printf("Setting Channel %d to %dV...\n", i, volt);
257         out_be16((void *)&(out[i].val), (volt * 0x7fff) / 10);
258         udelay(10000);
259         val = in_be16((void *)&(in[i*2].val));
260         printf("-> InChannel %d: 0x%04x=%dV\n", i*2, val, (val * 4000) / 0x7fff);
261         if ((val < ((volt * 0x7fff) / 40) - ERROR_DELTA) ||
262             (val > ((volt * 0x7fff) / 40) + ERROR_DELTA)) {
263                 printf("ERROR! (min=0x%04x max=0x%04x)\n", ((volt * 0x7fff) / 40) - ERROR_DELTA,
264                        ((volt * 0x7fff) / 40) + ERROR_DELTA);
265                 return -1;
266         }
267         val = in_be16((void *)&(in[i*2+1].val));
268         printf("-> InChannel %d: 0x%04x=%dV\n", i*2+1, val, (val * 4000) / 0x7fff);
269         if ((val < ((volt * 0x7fff) / 40) - ERROR_DELTA) ||
270             (val > ((volt * 0x7fff) / 40) + ERROR_DELTA)) {
271                 printf("ERROR! (min=0x%04x max=0x%04x)\n", ((volt * 0x7fff) / 40) - ERROR_DELTA,
272                        ((volt * 0x7fff) / 40) + ERROR_DELTA);
273                 return -1;
274         }
275
276         volt = 5;
277         printf("Setting Channel %d to %dV...\n", i, volt);
278         out_be16((void *)&(out[i].val), (volt * 0x7fff) / 10);
279         udelay(10000);
280         val = in_be16((void *)&(in[i*2].val));
281         printf("-> InChannel %d: 0x%04x=%dV\n", i*2, val, (val * 4000) / 0x7fff);
282         if ((val < ((volt * 0x7fff) / 40) - ERROR_DELTA) ||
283             (val > ((volt * 0x7fff) / 40) + ERROR_DELTA)) {
284                 printf("ERROR! (min=0x%04x max=0x%04x)\n", ((volt * 0x7fff) / 40) - ERROR_DELTA,
285                        ((volt * 0x7fff) / 40) + ERROR_DELTA);
286                 return -1;
287         }
288         val = in_be16((void *)&(in[i*2+1].val));
289         printf("-> InChannel %d: 0x%04x=%dV\n", i*2+1, val, (val * 4000) / 0x7fff);
290         if ((val < ((volt * 0x7fff) / 40) - ERROR_DELTA) ||
291             (val > ((volt * 0x7fff) / 40) + ERROR_DELTA)) {
292                 printf("ERROR! (min=0x%04x max=0x%04x)\n", ((volt * 0x7fff) / 40) - ERROR_DELTA,
293                        ((volt * 0x7fff) / 40) + ERROR_DELTA);
294                 return -1;
295         }
296
297         volt = 10;
298         printf("Setting Channel %d to %dV...\n", i, volt);
299         out_be16((void *)&(out[i].val), (volt * 0x7fff) / 10);
300         udelay(10000);
301         val = in_be16((void *)&(in[i*2].val));
302         printf("-> InChannel %d: 0x%04x=%dV\n", i*2, val, (val * 4000) / 0x7fff);
303         if ((val < ((volt * 0x7fff) / 40) - ERROR_DELTA) ||
304             (val > ((volt * 0x7fff) / 40) + ERROR_DELTA)) {
305                 printf("ERROR! (min=0x%04x max=0x%04x)\n", ((volt * 0x7fff) / 40) - ERROR_DELTA,
306                        ((volt * 0x7fff) / 40) + ERROR_DELTA);
307                 return -1;
308         }
309         val = in_be16((void *)&(in[i*2+1].val));
310         printf("-> InChannel %d: 0x%04x=%dV\n", i*2+1, val, (val * 4000) / 0x7fff);
311         if ((val < ((volt * 0x7fff) / 40) - ERROR_DELTA) ||
312             (val > ((volt * 0x7fff) / 40) + ERROR_DELTA)) {
313                 printf("ERROR! (min=0x%04x max=0x%04x)\n", ((volt * 0x7fff) / 40) - ERROR_DELTA,
314                        ((volt * 0x7fff) / 40) + ERROR_DELTA);
315                 return -1;
316         }
317
318         printf("Channel %d OK!\n", i);
319
320         return 0;
321 }
322 U_BOOT_CMD(
323         anatest,        2,      1,      do_anatest,
324         "Test analog in-/output",
325         ""
326 );
327
328
329 int counter = 0;
330
331 void cyclicInt(void *ptr)
332 {
333         out_be16((void *)0xf03000e8, 0x0800); /* ack int */
334         counter++;
335 }
336
337
338 int do_inctest(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
339 {
340         ulong *incin;
341         int i;
342
343         incin = (ulong *)0xf0300040;
344
345         /*
346          * Clear inc counter
347          */
348         out_be32((void *)&incin[0], 0);
349         out_be32((void *)&incin[1], 0);
350         out_be32((void *)&incin[2], 0);
351         out_be32((void *)&incin[3], 0);
352
353         incin = (ulong *)0xf0300050;
354
355         /*
356          * Inc a little
357          */
358         for (i=0; i<10000; i++) {
359                 switch (i & 0x03) {
360                 case 0:
361                         out_8(DIGEN, 0x02);
362                         break;
363                 case 1:
364                         out_8(DIGEN, 0x03);
365                         break;
366                 case 2:
367                         out_8(DIGEN, 0x01);
368                         break;
369                 case 3:
370                         out_8(DIGEN, 0x00);
371                         break;
372                 }
373                 udelay(10);
374         }
375
376         printf("Inc 0 = %d\n", in_be32((void *)&incin[0]));
377         printf("Inc 1 = %d\n", in_be32((void *)&incin[1]));
378         printf("Inc 2 = %d\n", in_be32((void *)&incin[2]));
379         printf("Inc 3 = %d\n", in_be32((void *)&incin[3]));
380
381         out_be16((void *)0xf03000e0, 0x0c80-1); /* set counter */
382         out_be16((void *)0xf03000ec,
383                  in_be16((void *)0xf03000ec) | 0x0800); /* enable int */
384         irq_install_handler (30, (interrupt_handler_t *) cyclicInt, NULL);
385         printf("counter=%d\n", counter);
386
387         return 0;
388 }
389 U_BOOT_CMD(
390         inctest,        3,      1,      do_inctest,
391         "Test incremental encoder inputs",
392         ""
393 );
394 #endif