]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/esd/pci405/pci405.c
44bfe107feb54ba8bb7abc668755cb7bf39fb1fe
[karo-tx-uboot.git] / board / esd / pci405 / pci405.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 <malloc.h>
28 #include <pci.h>
29 #include <405gp_pci.h>
30
31 #include "pci405.h"
32
33
34 /* ------------------------------------------------------------------------- */
35 extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);/*cmd_boot.c*/
36 #if 0
37 #define FPGA_DEBUG
38 #endif
39
40 /* fpga configuration data - generated by bin2cc */
41 const unsigned char fpgadata[] =
42 {
43 #include "fpgadata.c"
44 };
45
46 /*
47  * include common fpga code (for esd boards)
48  */
49 #include "../common/fpga.c"
50
51
52 /* Prototypes */
53 int gunzip(void *, int, unsigned char *, int *);
54
55
56 int board_early_init_f (void)
57 {
58         unsigned long cntrl0Reg;
59
60         /*
61          * IRQ 0-15  405GP internally generated; active high; level sensitive
62          * IRQ 16    405GP internally generated; active low; level sensitive
63          * IRQ 17-24 RESERVED
64          * IRQ 25 (EXT IRQ 0) CAN0; active low; level sensitive
65          * IRQ 26 (EXT IRQ 1) CAN1; active low; level sensitive
66          * IRQ 27 (EXT IRQ 2) CAN2; active low; level sensitive
67          * IRQ 28 (EXT IRQ 3) CAN3; active low; level sensitive
68          * IRQ 29 (EXT IRQ 4) unused; active low; level sensitive
69          * IRQ 30 (EXT IRQ 5) FPGA Timestamp; active low; level sensitive
70          * IRQ 31 (EXT IRQ 6) PCI Reset; active low; level sensitive
71          */
72         mtdcr(uicsr, 0xFFFFFFFF);        /* clear all ints */
73         mtdcr(uicer, 0x00000000);        /* disable all ints */
74         mtdcr(uiccr, 0x00000000);        /* set all to be non-critical*/
75         mtdcr(uicpr, 0xFFFFFF80);        /* set int polarities */
76         mtdcr(uictr, 0x10000000);        /* set int trigger levels */
77         mtdcr(uicvcr, 0x00000001);       /* set vect base=0,INT0 highest priority*/
78         mtdcr(uicsr, 0xFFFFFFFF);        /* clear all ints */
79
80         /*
81          * Setup GPIO pins (IRQ4/GPIO21 as GPIO)
82          */
83         cntrl0Reg = mfdcr(cntrl0);
84         mtdcr(cntrl0, cntrl0Reg | 0x00008000);
85
86         /*
87          * EBC Configuration Register: set ready timeout to 512 ebc-clks -> ca. 25 us
88          */
89         mtebc (epcr, 0xa8400000); /* ebc always driven */
90
91         return 0;
92 }
93
94
95 /* ------------------------------------------------------------------------- */
96
97 int misc_init_f (void)
98 {
99         return 0;  /* dummy implementation */
100 }
101
102
103 int misc_init_r (void)
104 {
105         unsigned char *dst;
106         ulong len = sizeof(fpgadata);
107         int status;
108         int index;
109         int i;
110         unsigned int *ptr;
111         unsigned int *magic;
112
113         /*
114          * On PCI-405 the environment is saved in eeprom!
115          * FPGA can be gzip compressed (malloc) and booted this late.
116          */
117
118         dst = malloc(CFG_FPGA_MAX_SIZE);
119         if (gunzip (dst, CFG_FPGA_MAX_SIZE, (uchar *)fpgadata, (int *)&len) != 0) {
120                 printf ("GUNZIP ERROR - must RESET board to recover\n");
121                 do_reset (NULL, 0, 0, NULL);
122         }
123
124         status = fpga_boot(dst, len);
125         if (status != 0) {
126                 printf("\nFPGA: Booting failed ");
127                 switch (status) {
128                 case ERROR_FPGA_PRG_INIT_LOW:
129                         printf("(Timeout: INIT not low after asserting PROGRAM*)\n ");
130                         break;
131                 case ERROR_FPGA_PRG_INIT_HIGH:
132                         printf("(Timeout: INIT not high after deasserting PROGRAM*)\n ");
133                         break;
134                 case ERROR_FPGA_PRG_DONE:
135                         printf("(Timeout: DONE not high after programming FPGA)\n ");
136                         break;
137                 }
138
139                 /* display infos on fpgaimage */
140                 index = 15;
141                 for (i=0; i<4; i++) {
142                         len = dst[index];
143                         printf("FPGA: %s\n", &(dst[index+1]));
144                         index += len+3;
145                 }
146                 putc ('\n');
147                 /* delayed reboot */
148                 for (i=20; i>0; i--) {
149                         printf("Rebooting in %2d seconds \r",i);
150                         for (index=0;index<1000;index++)
151                                 udelay(1000);
152                 }
153                 putc ('\n');
154                 do_reset(NULL, 0, 0, NULL);
155         }
156
157         puts("FPGA:  ");
158
159         /* display infos on fpgaimage */
160         index = 15;
161         for (i=0; i<4; i++) {
162                 len = dst[index];
163                 printf("%s ", &(dst[index+1]));
164                 index += len+3;
165         }
166         putc ('\n');
167
168         /*
169          * Reset FPGA via FPGA_DATA pin
170          */
171         SET_FPGA(FPGA_PRG | FPGA_CLK);
172         udelay(1000); /* wait 1ms */
173         SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);
174         udelay(1000); /* wait 1ms */
175
176         /*
177          * Check if magic for pci reconfig is written
178          */
179         magic = (unsigned int *)0x00000004;
180         if (*magic == PCI_RECONFIG_MAGIC) {
181                 /*
182                  * Rewrite pci config regs (only after soft-reset with magic set)
183                  */
184                 ptr = (unsigned int *)PCI_REGS_ADDR;
185                 if (crc32(0, (char *)PCI_REGS_ADDR+4, PCI_REGS_LEN-4) == *ptr) {
186                         puts("Restoring PCI Configurations Regs!\n");
187                         ptr = (unsigned int *)PCI_REGS_ADDR + 1;
188                         for (i=0; i<0x40; i+=4) {
189                                 pci_write_config_dword(PCIDEVID_405GP, i, *ptr++);
190                         }
191                 }
192                 mtdcr(uicsr, 0xFFFFFFFF);        /* clear all ints */
193
194                 *magic = 0;      /* clear pci reconfig magic again */
195         }
196
197         free(dst);
198         return (0);
199 }
200
201
202 /*
203  * Check Board Identity:
204  */
205
206 int checkboard (void)
207 {
208         unsigned char str[64];
209         int i = getenv_r ("serial#", str, sizeof(str));
210
211         puts ("Board: ");
212
213         if (i == -1) {
214                 puts ("### No HW ID - assuming PCI405");
215         } else {
216                 puts (str);
217         }
218         putc ('\n');
219
220         return 0;
221 }
222
223 /* ------------------------------------------------------------------------- */
224
225 long int initdram (int board_type)
226 {
227         unsigned long val;
228
229         mtdcr(memcfga, mem_mb0cf);
230         val = mfdcr(memcfgd);
231
232 #if 0
233         printf("\nmb0cf=%x\n", val); /* test-only */
234         printf("strap=%x\n", mfdcr(strap)); /* test-only */
235 #endif
236
237 #if 0 /* test-only: all PCI405 version must report 16mb */
238         return (4*1024*1024 << ((val & 0x000e0000) >> 17));
239 #else
240         return (16*1024*1024);
241 #endif
242 }
243
244 /* ------------------------------------------------------------------------- */
245
246 int testdram (void)
247 {
248         /* TODO: XXX XXX XXX */
249         printf ("test: 16 MB - ok\n");
250
251         return (0);
252 }
253
254 /* ------------------------------------------------------------------------- */