]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/esd/cpci405/cpci405.c
Initial revision
[karo-tx-uboot.git] / board / esd / cpci405 / cpci405.c
1 /*
2  * (C) Copyright 2001
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 <asm/processor.h>
26 #include <command.h>
27 #include <cmd_boot.h>
28 #include <malloc.h>
29
30 /* ------------------------------------------------------------------------- */
31
32 #if 0
33 #define FPGA_DEBUG
34 #endif
35
36 /* fpga configuration data - generated by bin2cc */
37 const unsigned char fpgadata[] =
38 {
39 #ifdef CONFIG_CPCI405_VER2
40 # include "fpgadata_cpci4052.c"
41 #else
42 # include "fpgadata_cpci405.c"
43 #endif
44 };
45
46 /*
47  * include common fpga code (for esd boards)
48  */
49 #include "../common/fpga.c"
50
51
52 /* Prototypes */
53 int version2(void);
54 int gunzip(void *, int, unsigned char *, int *);
55
56
57 int board_pre_init (void)
58 {
59 #ifndef CONFIG_CPCI405_VER2
60         int index, len, i;
61         int status;
62 #endif
63
64 #ifdef FPGA_DEBUG
65         DECLARE_GLOBAL_DATA_PTR;
66
67         /* set up serial port with default baudrate */
68         (void) get_clocks ();
69         gd->baudrate = CONFIG_BAUDRATE;
70         serial_init ();
71         console_init_f();
72 #endif
73
74         /*
75          * First pull fpga-prg pin low, to disable fpga logic (on version 2 board)
76          */
77         out32(IBM405GP_GPIO0_ODR, 0x00000000);        /* no open drain pins      */
78         out32(IBM405GP_GPIO0_TCR, CFG_FPGA_PRG);      /* setup for output        */
79         out32(IBM405GP_GPIO0_OR,  CFG_FPGA_PRG);      /* set output pins to high */
80         out32(IBM405GP_GPIO0_OR, 0);                  /* pull prg low            */
81
82         /*
83          * Boot onboard FPGA
84          */
85 #ifndef CONFIG_CPCI405_VER2
86         if (!version2()) {
87                 status = fpga_boot((unsigned char *)fpgadata, sizeof(fpgadata));
88                 if (status != 0) {
89                         /* booting FPGA failed */
90 #ifndef FPGA_DEBUG
91                         DECLARE_GLOBAL_DATA_PTR;
92
93                         /* set up serial port with default baudrate */
94                         (void) get_clocks ();
95                         gd->baudrate = CONFIG_BAUDRATE;
96                         serial_init ();
97                         console_init_f();
98 #endif
99                         printf("\nFPGA: Booting failed ");
100                         switch (status) {
101                         case ERROR_FPGA_PRG_INIT_LOW:
102                                 printf("(Timeout: INIT not low after asserting PROGRAM*)\n ");
103                                 break;
104                         case ERROR_FPGA_PRG_INIT_HIGH:
105                                 printf("(Timeout: INIT not high after deasserting PROGRAM*)\n ");
106                                 break;
107                         case ERROR_FPGA_PRG_DONE:
108                                 printf("(Timeout: DONE not high after programming FPGA)\n ");
109                                 break;
110                         }
111
112                         /* display infos on fpgaimage */
113                         index = 15;
114                         for (i=0; i<4; i++) {
115                                 len = fpgadata[index];
116                                 printf("FPGA: %s\n", &(fpgadata[index+1]));
117                                 index += len+3;
118                         }
119                         putc ('\n');
120                         /* delayed reboot */
121                         for (i=20; i>0; i--) {
122                                 printf("Rebooting in %2d seconds \r",i);
123                                 for (index=0;index<1000;index++)
124                                         udelay(1000);
125                         }
126                         putc ('\n');
127                         do_reset(NULL, 0, 0, NULL);
128                 }
129         }
130 #endif /* !CONFIG_CPCI405_VER2 */
131
132         /*
133          * IRQ 0-15  405GP internally generated; active high; level sensitive
134          * IRQ 16    405GP internally generated; active low; level sensitive
135          * IRQ 17-24 RESERVED
136          * IRQ 25 (EXT IRQ 0) CAN0; active low; level sensitive
137          * IRQ 26 (EXT IRQ 1) CAN1 (+FPGA on CPCI4052) ; active low; level sensitive
138          * IRQ 27 (EXT IRQ 2) PCI SLOT 0; active low; level sensitive
139          * IRQ 28 (EXT IRQ 3) PCI SLOT 1; active low; level sensitive
140          * IRQ 29 (EXT IRQ 4) PCI SLOT 2; active low; level sensitive
141          * IRQ 30 (EXT IRQ 5) PCI SLOT 3; active low; level sensitive
142          * IRQ 31 (EXT IRQ 6) COMPACT FLASH; active high; level sensitive
143          */
144         mtdcr(uicsr, 0xFFFFFFFF);       /* clear all ints */
145         mtdcr(uicer, 0x00000000);       /* disable all ints */
146         mtdcr(uiccr, 0x00000000);       /* set all to be non-critical*/
147         mtdcr(uicpr, 0xFFFFFF81);       /* set int polarities */
148         mtdcr(uictr, 0x10000000);       /* set int trigger levels */
149         mtdcr(uicvcr, 0x00000001);      /* set vect base=0,INT0 highest priority*/
150         mtdcr(uicsr, 0xFFFFFFFF);       /* clear all ints */
151
152         return 0;
153 }
154
155
156 /* ------------------------------------------------------------------------- */
157
158 int ctermm2(void)
159 {
160 #ifdef CONFIG_CPCI405_VER2
161         return 0;                       /* no, board is cpci405 */
162 #else
163         if ((*(unsigned char *)0xf0000400 == 0x00) &&
164             (*(unsigned char *)0xf0000401 == 0x01))
165                 return 0;               /* no, board is cpci405 */
166         else
167                 return -1;              /* yes, board is cterm-m2 */
168 #endif
169 }
170
171
172 int cpci405_host(void)
173 {
174         if (mfdcr(strap) & PSR_PCI_ARBIT_EN)
175                 return -1;              /* yes, board is cpci405 host */
176         else
177                 return 0;               /* no, board is cpci405 adapter */
178 }
179
180
181 int version2(void)
182 {
183         unsigned long cntrl0Reg;
184         unsigned long value;
185
186         /*
187          * Setup GPIO pins (CS2/GPIO11 as GPIO)
188          */
189         cntrl0Reg = mfdcr(cntrl0);
190         mtdcr(cntrl0, cntrl0Reg | 0x02000000);
191
192         udelay(1000);                   /* wait some time before reading input */
193         value = in32(IBM405GP_GPIO0_IR) & 0x00100000; /* test GPIO11 */
194
195         /*
196          * Setup GPIO pins (CS2/GPIO11 as CS again)
197          */
198         mtdcr(cntrl0, cntrl0Reg);
199
200         if (value)
201                 return 0;               /* no, board is version 1.x */
202         else
203                 return -1;              /* yes, board is version 2.x */
204 }
205
206
207 int misc_init_f (void)
208 {
209         return 0;  /* dummy implementation */
210 }
211
212
213 int misc_init_r (void)
214 {
215         DECLARE_GLOBAL_DATA_PTR;
216
217         bd_t *bd = gd->bd;
218         char *  tmp;                    /* Temporary char pointer      */
219
220 #ifdef CONFIG_CPCI405_VER2
221         unsigned char *dst;
222         ulong len = sizeof(fpgadata);
223         int status;
224         int index;
225         int i;
226         unsigned long cntrl0Reg;
227
228         /*
229          * On CPCI-405 version 2 the environment is saved in eeprom!
230          * FPGA can be gzip compressed (malloc) and booted this late.
231          */
232
233         if (version2()) {
234                 /*
235                  * Setup GPIO pins (CS6+CS7 as GPIO)
236                  */
237                 cntrl0Reg = mfdcr(cntrl0);
238                 mtdcr(cntrl0, cntrl0Reg | 0x00300000);
239
240                 dst = malloc(CFG_FPGA_MAX_SIZE);
241                 if (gunzip (dst, CFG_FPGA_MAX_SIZE, (uchar *)fpgadata, (int *)&len) != 0) {
242                         printf ("GUNZIP ERROR - must RESET board to recover\n");
243                         do_reset (NULL, 0, 0, NULL);
244                 }
245
246                 status = fpga_boot(dst, len);
247                 if (status != 0) {
248                         printf("\nFPGA: Booting failed ");
249                         switch (status) {
250                         case ERROR_FPGA_PRG_INIT_LOW:
251                                 printf("(Timeout: INIT not low after asserting PROGRAM*)\n ");
252                                 break;
253                         case ERROR_FPGA_PRG_INIT_HIGH:
254                                 printf("(Timeout: INIT not high after deasserting PROGRAM*)\n ");
255                                 break;
256                         case ERROR_FPGA_PRG_DONE:
257                                 printf("(Timeout: DONE not high after programming FPGA)\n ");
258                                 break;
259                         }
260
261                         /* display infos on fpgaimage */
262                         index = 15;
263                         for (i=0; i<4; i++) {
264                                 len = dst[index];
265                                 printf("FPGA: %s\n", &(dst[index+1]));
266                                 index += len+3;
267                         }
268                         putc ('\n');
269                         /* delayed reboot */
270                         for (i=20; i>0; i--) {
271                                 printf("Rebooting in %2d seconds \r",i);
272                                 for (index=0;index<1000;index++)
273                                         udelay(1000);
274                         }
275                         putc ('\n');
276                         do_reset(NULL, 0, 0, NULL);
277                 }
278
279                 /* restore gpio/cs settings */
280                 mtdcr(cntrl0, cntrl0Reg);
281
282                 puts("FPGA:  ");
283
284                 /* display infos on fpgaimage */
285                 index = 15;
286                 for (i=0; i<4; i++) {
287                         len = dst[index];
288                         printf("%s ", &(dst[index+1]));
289                         index += len+3;
290                 }
291                 putc ('\n');
292
293                 free(dst);
294         }
295         else {
296                 printf("\n*** U-Boot Version does not match Board Version!\n");
297                 printf("*** CPCI-405 Version 2.x detected!\n");
298                 printf("*** Please use correct U-Boot version (CPCI4052)!\n\n");
299         }
300
301 #else /* CONFIG_CPCI405_VER2 */
302
303         /*
304          * Generate last byte of ip-addr from code-plug @ 0xf0000400
305          */
306         if (ctermm2()) {
307                 char str[32];
308                 unsigned char ipbyte = *(unsigned char *)0xf0000400;
309
310                 /*
311                  * Only overwrite ip-addr with allowed values
312                  */
313                 if ((ipbyte != 0x00) && (ipbyte != 0xff)) {
314                         bd->bi_ip_addr = (bd->bi_ip_addr & 0xffffff00) | ipbyte;
315                         sprintf(str, "%ld.%ld.%ld.%ld",
316                                 (bd->bi_ip_addr & 0xff000000) >> 24,
317                                 (bd->bi_ip_addr & 0x00ff0000) >> 16,
318                                 (bd->bi_ip_addr & 0x0000ff00) >> 8,
319                                 (bd->bi_ip_addr & 0x000000ff));
320                         setenv("ipaddr", str);
321                 }
322         }
323
324         if (version2()) {
325                 printf("\n*** U-Boot Version does not match Board Version!\n");
326                 printf("*** CPCI-405 Board Version 1.x detected!\n");
327                 printf("*** Please use correct U-Boot version (CPCI405)!\n\n");
328         }
329
330 #endif /* CONFIG_CPCI405_VER2 */
331
332         /*
333          * Write ethernet addr in NVRAM for VxWorks
334          */
335         tmp = (char *)CFG_NVRAM_BASE_ADDR + CFG_NVRAM_VXWORKS_OFFS;
336         memcpy( (char *)tmp, (char *)&bd->bi_enetaddr[0], 6 );
337         return (0);
338 }
339
340
341 /*
342  * Check Board Identity:
343  */
344
345 int checkboard (void)
346 {
347 #ifndef CONFIG_CPCI405_VER2
348         int index;
349         int len;
350 #endif
351         unsigned char str[64];
352         int i = getenv_r ("serial#", str, sizeof(str));
353
354         puts ("Board: ");
355
356         if (i == -1) {
357                 puts ("### No HW ID - assuming CPCI405");
358         } else {
359                 puts(str);
360         }
361
362         if (version2())
363                 puts (" (Ver 2.x, ");
364         else
365                 puts (" (Ver 1.x, ");
366
367 #if 0
368         if ((*(unsigned short *)((unsigned long)CFG_FPGA_BASE_ADDR) + CFG_FPGA_STATUS)
369             & CFG_FPGA_STATUS_FLASH)
370                 puts ("FLASH Bank A, ");
371         else
372                 puts ("FLASH Bank B, ");
373 #endif
374
375         if (ctermm2()) {
376                 printf("CTERM-M2 - Id=0x%02x)", *(unsigned char *)0xf0000400);
377         } else {
378                 if (cpci405_host()) {
379                         puts ("PCI Host Version)");
380                 } else {
381                         puts ("PCI Adapter Version)");
382                 }
383         }
384
385 #ifndef CONFIG_CPCI405_VER2
386         puts ("\nFPGA:  ");
387
388         /* display infos on fpgaimage */
389         index = 15;
390         for (i=0; i<4; i++) {
391                 len = fpgadata[index];
392                 printf("%s ", &(fpgadata[index+1]));
393                 index += len+3;
394         }
395 #endif
396
397         putc ('\n');
398
399         return 0;
400 }
401
402 /* ------------------------------------------------------------------------- */
403
404 long int initdram (int board_type)
405 {
406         unsigned long val;
407
408         mtdcr(memcfga, mem_mb0cf);
409         val = mfdcr(memcfgd);
410
411 #if 0
412         printf("\nmb0cf=%x\n", val); /* test-only */
413         printf("strap=%x\n", mfdcr(strap)); /* test-only */
414 #endif
415
416         return (4*1024*1024 << ((val & 0x000e0000) >> 17));
417 }
418
419 /* ------------------------------------------------------------------------- */
420
421 int testdram (void)
422 {
423         /* TODO: XXX XXX XXX */
424         printf ("test: 16 MB - ok\n");
425
426         return (0);
427 }
428
429 /* ------------------------------------------------------------------------- */
430
431 #ifdef CONFIG_CPCI405_VER2
432 #ifdef CONFIG_IDE_RESET
433
434 void ide_set_reset(int on)
435 {
436         volatile unsigned short *fpga_mode = (unsigned short *)CFG_FPGA_BASE_ADDR;
437
438         /*
439          * Assert or deassert CompactFlash Reset Pin
440          */
441         if (on) {               /* assert RESET */
442                 *fpga_mode &= ~(CFG_FPGA_MODE_CF_RESET);
443         } else {                /* release RESET */
444                 *fpga_mode |= CFG_FPGA_MODE_CF_RESET;
445         }
446 }
447
448 #endif /* CONFIG_IDE_RESET */
449 #endif /* CONFIG_CPCI405_VER2 */
450
451 /* ------------------------------------------------------------------------- */