]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/esd/cpci405/cpci405.c
Changed CPCI405 to use CTS instead of DSR on PPC405 UART1.
[karo-tx-uboot.git] / board / esd / cpci405 / cpci405.c
1 /*
2  * (C) Copyright 2001-2003
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 cpci405_version(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 (cpci405_version() == 1) {
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         if (cpci405_version() == 3) {
148                 mtdcr(uicpr, 0xFFFFFF99);       /* set int polarities */
149         } else {
150                 mtdcr(uicpr, 0xFFFFFF81);       /* set int polarities */
151         }
152         mtdcr(uictr, 0x10000000);       /* set int trigger levels */
153         mtdcr(uicvcr, 0x00000001);      /* set vect base=0,INT0 highest priority*/
154         mtdcr(uicsr, 0xFFFFFFFF);       /* clear all ints */
155
156         return 0;
157 }
158
159
160 /* ------------------------------------------------------------------------- */
161
162 int ctermm2(void)
163 {
164 #ifdef CONFIG_CPCI405_VER2
165         return 0;                       /* no, board is cpci405 */
166 #else
167         if ((*(unsigned char *)0xf0000400 == 0x00) &&
168             (*(unsigned char *)0xf0000401 == 0x01))
169                 return 0;               /* no, board is cpci405 */
170         else
171                 return -1;              /* yes, board is cterm-m2 */
172 #endif
173 }
174
175
176 int cpci405_host(void)
177 {
178         if (mfdcr(strap) & PSR_PCI_ARBIT_EN)
179                 return -1;              /* yes, board is cpci405 host */
180         else
181                 return 0;               /* no, board is cpci405 adapter */
182 }
183
184
185 int cpci405_version(void)
186 {
187         unsigned long cntrl0Reg;
188         unsigned long value;
189
190         /*
191          * Setup GPIO pins (CS2/GPIO11 and CS3/GPIO12 as GPIO)
192          */
193         cntrl0Reg = mfdcr(cntrl0);
194         mtdcr(cntrl0, cntrl0Reg | 0x03000000);
195         out32(IBM405GP_GPIO0_ODR, in32(IBM405GP_GPIO0_ODR) & ~0x00180000);
196         out32(IBM405GP_GPIO0_TCR, in32(IBM405GP_GPIO0_TCR) & ~0x00180000);
197         udelay(1000);                   /* wait some time before reading input */
198         value = in32(IBM405GP_GPIO0_IR) & 0x00180000;       /* get config bits */
199
200         /*
201          * Restore GPIO settings
202          */
203         mtdcr(cntrl0, cntrl0Reg);
204
205         switch (value) {
206         case 0x00180000:
207                 /* CS2==1 && CS3==1 -> version 1 */
208                 return 1;
209         case 0x00080000:
210                 /* CS2==0 && CS3==1 -> version 2 */
211                 return 2;
212         case 0x00100000:
213                 /* CS2==1 && CS3==0 -> version 3 */
214                 return 3;
215         case 0x00000000:
216                 /* CS2==0 && CS3==0 -> version 4 */
217                 return 4;
218         default:
219                 /* should not be reached! */
220                 return 2;
221         }
222 }
223
224
225 int misc_init_f (void)
226 {
227         return 0;  /* dummy implementation */
228 }
229
230
231 int misc_init_r (void)
232 {
233         DECLARE_GLOBAL_DATA_PTR;
234
235         bd_t *bd = gd->bd;
236         char *  tmp;                    /* Temporary char pointer      */
237         unsigned long cntrl0Reg;
238
239 #ifdef CONFIG_CPCI405_VER2
240         unsigned char *dst;
241         ulong len = sizeof(fpgadata);
242         int status;
243         int index;
244         int i;
245
246         /*
247          * On CPCI-405 version 2 the environment is saved in eeprom!
248          * FPGA can be gzip compressed (malloc) and booted this late.
249          */
250
251         if (cpci405_version() >= 2) {
252                 /*
253                  * Setup GPIO pins (CS6+CS7 as GPIO)
254                  */
255                 cntrl0Reg = mfdcr(cntrl0);
256                 mtdcr(cntrl0, cntrl0Reg | 0x00300000);
257
258                 dst = malloc(CFG_FPGA_MAX_SIZE);
259                 if (gunzip (dst, CFG_FPGA_MAX_SIZE, (uchar *)fpgadata, (int *)&len) != 0) {
260                         printf ("GUNZIP ERROR - must RESET board to recover\n");
261                         do_reset (NULL, 0, 0, NULL);
262                 }
263
264                 status = fpga_boot(dst, len);
265                 if (status != 0) {
266                         printf("\nFPGA: Booting failed ");
267                         switch (status) {
268                         case ERROR_FPGA_PRG_INIT_LOW:
269                                 printf("(Timeout: INIT not low after asserting PROGRAM*)\n ");
270                                 break;
271                         case ERROR_FPGA_PRG_INIT_HIGH:
272                                 printf("(Timeout: INIT not high after deasserting PROGRAM*)\n ");
273                                 break;
274                         case ERROR_FPGA_PRG_DONE:
275                                 printf("(Timeout: DONE not high after programming FPGA)\n ");
276                                 break;
277                         }
278
279                         /* display infos on fpgaimage */
280                         index = 15;
281                         for (i=0; i<4; i++) {
282                                 len = dst[index];
283                                 printf("FPGA: %s\n", &(dst[index+1]));
284                                 index += len+3;
285                         }
286                         putc ('\n');
287                         /* delayed reboot */
288                         for (i=20; i>0; i--) {
289                                 printf("Rebooting in %2d seconds \r",i);
290                                 for (index=0;index<1000;index++)
291                                         udelay(1000);
292                         }
293                         putc ('\n');
294                         do_reset(NULL, 0, 0, NULL);
295                 }
296
297                 /* restore gpio/cs settings */
298                 mtdcr(cntrl0, cntrl0Reg);
299
300                 puts("FPGA:  ");
301
302                 /* display infos on fpgaimage */
303                 index = 15;
304                 for (i=0; i<4; i++) {
305                         len = dst[index];
306                         printf("%s ", &(dst[index+1]));
307                         index += len+3;
308                 }
309                 putc ('\n');
310
311                 free(dst);
312
313                 /*
314                  * Reset FPGA via FPGA_DATA pin
315                  */
316                 SET_FPGA(FPGA_PRG | FPGA_CLK);
317                 udelay(1000); /* wait 1ms */
318                 SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);
319                 udelay(1000); /* wait 1ms */
320
321                 if (cpci405_version() == 3) {
322                         volatile unsigned short *fpga_mode = (unsigned short *)CFG_FPGA_BASE_ADDR;
323                         volatile unsigned char *leds = (unsigned char *)CFG_LED_ADDR;
324
325                         /*
326                          * Enable outputs in fpga on version 3 board
327                          */
328                         *fpga_mode |= CFG_FPGA_MODE_ENABLE_OUTPUT;
329
330                         /*
331                          * Set outputs to 0
332                          */
333                         *leds = 0x00;
334
335                         /*
336                          * Reset external DUART
337                          */
338                         *fpga_mode |= CFG_FPGA_MODE_DUART_RESET;
339                         udelay(100);
340                         *fpga_mode &= ~(CFG_FPGA_MODE_DUART_RESET);
341                 }
342         }
343         else {
344                 puts("\n*** U-Boot Version does not match Board Version!\n");
345                 puts("*** CPCI-405 Version 1.x detected!\n");
346                 puts("*** Please use correct U-Boot version (CPCI405 instead of CPCI4052)!\n\n");
347         }
348
349 #else /* CONFIG_CPCI405_VER2 */
350
351         /*
352          * Generate last byte of ip-addr from code-plug @ 0xf0000400
353          */
354         if (ctermm2()) {
355                 char str[32];
356                 unsigned char ipbyte = *(unsigned char *)0xf0000400;
357
358                 /*
359                  * Only overwrite ip-addr with allowed values
360                  */
361                 if ((ipbyte != 0x00) && (ipbyte != 0xff)) {
362                         bd->bi_ip_addr = (bd->bi_ip_addr & 0xffffff00) | ipbyte;
363                         sprintf(str, "%ld.%ld.%ld.%ld",
364                                 (bd->bi_ip_addr & 0xff000000) >> 24,
365                                 (bd->bi_ip_addr & 0x00ff0000) >> 16,
366                                 (bd->bi_ip_addr & 0x0000ff00) >> 8,
367                                 (bd->bi_ip_addr & 0x000000ff));
368                         setenv("ipaddr", str);
369                 }
370         }
371
372         if (cpci405_version() >= 2) {
373                 puts("\n*** U-Boot Version does not match Board Version!\n");
374                 puts("*** CPCI-405 Board Version 2.x detected!\n");
375                 puts("*** Please use correct U-Boot version (CPCI4052 instead of CPCI405)!\n\n");
376         }
377
378 #endif /* CONFIG_CPCI405_VER2 */
379
380         /*
381          * Select cts (and not dsr) on uart1
382          */
383         cntrl0Reg = mfdcr(cntrl0);
384         mtdcr(cntrl0, cntrl0Reg | 0x00001000);
385
386         /*
387          * Write ethernet addr in NVRAM for VxWorks
388          */
389         tmp = (char *)CFG_NVRAM_BASE_ADDR + CFG_NVRAM_VXWORKS_OFFS;
390         memcpy( (char *)tmp, (char *)&bd->bi_enetaddr[0], 6 );
391         return (0);
392 }
393
394
395 /*
396  * Check Board Identity:
397  */
398
399 int checkboard (void)
400 {
401 #ifndef CONFIG_CPCI405_VER2
402         int index;
403         int len;
404 #endif
405         unsigned char str[64];
406         int i = getenv_r ("serial#", str, sizeof(str));
407         unsigned short ver;
408
409         puts ("Board: ");
410
411         if (i == -1) {
412                 puts ("### No HW ID - assuming CPCI405");
413         } else {
414                 puts(str);
415         }
416
417         ver = cpci405_version();
418         printf(" (Ver %d.x, ", ver);
419
420 #if 0 /* test-only */
421         if (ver >= 2) {
422                 volatile u16 *fpga_status = (u16 *)CFG_FPGA_BASE_ADDR + 1;
423
424                 if (*fpga_status & CFG_FPGA_STATUS_FLASH) {
425                         puts ("FLASH Bank B, ");
426                 } else {
427                         puts ("FLASH Bank A, ");
428                 }
429         }
430 #endif
431
432         if (ctermm2()) {
433                 printf("CTERM-M2 - Id=0x%02x)", *(unsigned char *)0xf0000400);
434         } else {
435                 if (cpci405_host()) {
436                         puts ("PCI Host Version)");
437                 } else {
438                         puts ("PCI Adapter Version)");
439                 }
440         }
441
442 #ifndef CONFIG_CPCI405_VER2
443         puts ("\nFPGA:  ");
444
445         /* display infos on fpgaimage */
446         index = 15;
447         for (i=0; i<4; i++) {
448                 len = fpgadata[index];
449                 printf("%s ", &(fpgadata[index+1]));
450                 index += len+3;
451         }
452 #endif
453
454         putc ('\n');
455
456         return 0;
457 }
458
459 /* ------------------------------------------------------------------------- */
460
461 long int initdram (int board_type)
462 {
463         unsigned long val;
464
465         mtdcr(memcfga, mem_mb0cf);
466         val = mfdcr(memcfgd);
467
468 #if 0
469         printf("\nmb0cf=%x\n", val); /* test-only */
470         printf("strap=%x\n", mfdcr(strap)); /* test-only */
471 #endif
472
473         return (4*1024*1024 << ((val & 0x000e0000) >> 17));
474 }
475
476 /* ------------------------------------------------------------------------- */
477
478 int testdram (void)
479 {
480         /* TODO: XXX XXX XXX */
481         printf ("test: 16 MB - ok\n");
482
483         return (0);
484 }
485
486 /* ------------------------------------------------------------------------- */
487
488 #ifdef CONFIG_CPCI405_VER2
489 #ifdef CONFIG_IDE_RESET
490
491 void ide_set_reset(int on)
492 {
493         volatile unsigned short *fpga_mode = (unsigned short *)CFG_FPGA_BASE_ADDR;
494
495         /*
496          * Assert or deassert CompactFlash Reset Pin
497          */
498         if (on) {               /* assert RESET */
499                 *fpga_mode &= ~(CFG_FPGA_MODE_CF_RESET);
500         } else {                /* release RESET */
501                 *fpga_mode |= CFG_FPGA_MODE_CF_RESET;
502         }
503 }
504
505 #endif /* CONFIG_IDE_RESET */
506 #endif /* CONFIG_CPCI405_VER2 */
507
508 /* ------------------------------------------------------------------------- */