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