PMC405 board added.
[platform/kernel/u-boot.git] / board / esd / pmc405 / pmc405.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
33 /* Prototypes */
34 int gunzip(void *, int, unsigned char *, int *);
35
36
37 int board_pre_init (void)
38 {
39         /*
40          * IRQ 0-15  405GP internally generated; active high; level sensitive
41          * IRQ 16    405GP internally generated; active low; level sensitive
42          * IRQ 17-24 RESERVED
43          * IRQ 25 (EXT IRQ 0) CAN0; active low; level sensitive
44          * IRQ 26 (EXT IRQ 1) SER0 ; active low; level sensitive
45          * IRQ 27 (EXT IRQ 2) SER1; active low; level sensitive
46          * IRQ 28 (EXT IRQ 3) FPGA 0; active low; level sensitive
47          * IRQ 29 (EXT IRQ 4) FPGA 1; active low; level sensitive
48          * IRQ 30 (EXT IRQ 5) PCI INTA; active low; level sensitive
49          * IRQ 31 (EXT IRQ 6) COMPACT FLASH; active high; level sensitive
50          */
51         mtdcr(uicsr, 0xFFFFFFFF);       /* clear all ints */
52         mtdcr(uicer, 0x00000000);       /* disable all ints */
53         mtdcr(uiccr, 0x00000000);       /* set all to be non-critical*/
54         mtdcr(uicpr, 0xFFFFFF81);       /* set int polarities */
55         mtdcr(uictr, 0x10000000);       /* set int trigger levels */
56         mtdcr(uicvcr, 0x00000001);      /* set vect base=0,INT0 highest priority*/
57         mtdcr(uicsr, 0xFFFFFFFF);       /* clear all ints */
58
59         /*
60          * EBC Configuration Register: set ready timeout to 512 ebc-clks -> ca. 15 us
61          */
62         mtebc (epcr, 0xa8400000);
63
64         return 0;
65 }
66
67
68 /* ------------------------------------------------------------------------- */
69
70 int misc_init_f (void)
71 {
72         return 0;  /* dummy implementation */
73 }
74
75
76 int misc_init_r (void)
77 {
78 #if 0 /* test-only */
79         DECLARE_GLOBAL_DATA_PTR;
80         volatile unsigned short *fpga_mode =
81                 (unsigned short *)((ulong)CFG_FPGA_BASE_ADDR + CFG_FPGA_CTRL);
82         volatile unsigned char *duart0_mcr =
83                 (unsigned char *)((ulong)DUART0_BA + 4);
84         volatile unsigned char *duart1_mcr =
85                 (unsigned char *)((ulong)DUART1_BA + 4);
86         bd_t *bd = gd->bd;
87         char *  tmp;                    /* Temporary char pointer      */
88         unsigned char *dst;
89         ulong len = sizeof(fpgadata);
90         int status;
91         int index;
92         int i;
93         unsigned long cntrl0Reg;
94
95         /*
96          * Setup GPIO pins (CS6+CS7 as GPIO)
97          */
98         cntrl0Reg = mfdcr(cntrl0);
99         mtdcr(cntrl0, cntrl0Reg | 0x00300000);
100
101         dst = malloc(CFG_FPGA_MAX_SIZE);
102         if (gunzip (dst, CFG_FPGA_MAX_SIZE, (uchar *)fpgadata, (int *)&len) != 0) {
103                 printf ("GUNZIP ERROR - must RESET board to recover\n");
104                 do_reset (NULL, 0, 0, NULL);
105         }
106
107         status = fpga_boot(dst, len);
108         if (status != 0) {
109                 printf("\nFPGA: Booting failed ");
110                 switch (status) {
111                 case ERROR_FPGA_PRG_INIT_LOW:
112                         printf("(Timeout: INIT not low after asserting PROGRAM*)\n ");
113                         break;
114                 case ERROR_FPGA_PRG_INIT_HIGH:
115                         printf("(Timeout: INIT not high after deasserting PROGRAM*)\n ");
116                         break;
117                 case ERROR_FPGA_PRG_DONE:
118                         printf("(Timeout: DONE not high after programming FPGA)\n ");
119                         break;
120                 }
121
122                 /* display infos on fpgaimage */
123                 index = 15;
124                 for (i=0; i<4; i++) {
125                         len = dst[index];
126                         printf("FPGA: %s\n", &(dst[index+1]));
127                         index += len+3;
128                 }
129                 putc ('\n');
130                 /* delayed reboot */
131                 for (i=20; i>0; i--) {
132                         printf("Rebooting in %2d seconds \r",i);
133                         for (index=0;index<1000;index++)
134                                 udelay(1000);
135                 }
136                 putc ('\n');
137                 do_reset(NULL, 0, 0, NULL);
138         }
139
140         /* restore gpio/cs settings */
141         mtdcr(cntrl0, cntrl0Reg);
142
143         puts("FPGA:  ");
144
145         /* display infos on fpgaimage */
146         index = 15;
147         for (i=0; i<4; i++) {
148                 len = dst[index];
149                 printf("%s ", &(dst[index+1]));
150                 index += len+3;
151         }
152         putc ('\n');
153
154         free(dst);
155
156         /*
157          * Reset FPGA via FPGA_DATA pin
158          */
159         SET_FPGA(FPGA_PRG | FPGA_CLK);
160         udelay(1000); /* wait 1ms */
161         SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);
162         udelay(1000); /* wait 1ms */
163
164         /*
165          * Enable power on PS/2 interface
166          */
167         *fpga_mode |= CFG_FPGA_CTRL_PS2_RESET;
168
169         /*
170          * Enable interrupts in exar duart mcr[3]
171          */
172         *duart0_mcr = 0x08;
173         *duart1_mcr = 0x08;
174 #endif
175
176         return (0);
177 }
178
179
180 /*
181  * Check Board Identity:
182  */
183
184 int checkboard (void)
185 {
186         unsigned char str[64];
187         int i = getenv_r ("serial#", str, sizeof(str));
188
189         puts ("Board: ");
190
191         if (i == -1) {
192                 puts ("### No HW ID - assuming ABG405");
193         } else {
194                 puts(str);
195         }
196
197         putc ('\n');
198
199         return 0;
200 }
201
202 /* ------------------------------------------------------------------------- */
203
204 long int initdram (int board_type)
205 {
206         unsigned long val;
207
208         mtdcr(memcfga, mem_mb0cf);
209         val = mfdcr(memcfgd);
210
211 #if 0
212         printf("\nmb0cf=%x\n", val); /* test-only */
213         printf("strap=%x\n", mfdcr(strap)); /* test-only */
214 #endif
215
216         return (4*1024*1024 << ((val & 0x000e0000) >> 17));
217 }
218
219 /* ------------------------------------------------------------------------- */
220
221 int testdram (void)
222 {
223         /* TODO: XXX XXX XXX */
224         printf ("test: 16 MB - ok\n");
225
226         return (0);
227 }
228
229 /* ------------------------------------------------------------------------- */