]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/quantum/fpga.c
imported Freescale specific U-Boot additions for i.MX28,... release L2.6.31_10.08.01
[karo-tx-uboot.git] / board / quantum / fpga.c
1 /*
2  * (C) Copyright 2001-2003
3  * Matthias Fuchs, esd gmbh germany, matthias.fuchs@esd-electronics.com
4  * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
5  *
6  * See file CREDITS for list of people who contributed to this
7  * project.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22  * MA 02111-1307 USA
23  */
24 /* The DEBUG define must be before common to enable debugging */
25 #undef DEBUG
26 #include <common.h>
27 #include <asm/processor.h>
28 #include <command.h>
29 #include "fpga.h"
30 /* ------------------------------------------------------------------------- */
31
32 #define MAX_ONES               226
33
34 /* MPC850 port D */
35 #define PD(bit) (1 << (15 - (bit)))
36 # define FPGA_INIT             PD(11)   /* FPGA init pin (ppc input)     */
37 # define FPGA_PRG              PD(12)   /* FPGA program pin (ppc output) */
38 # define FPGA_CLK              PD(13)   /* FPGA clk pin (ppc output)     */
39 # define FPGA_DATA             PD(14)   /* FPGA data pin (ppc output)    */
40 # define FPGA_DONE             PD(15)   /* FPGA done pin (ppc input)     */
41
42
43 /* DDR 0 - input, 1 - output */
44 #define FPGA_INIT_PDDIR          FPGA_PRG | FPGA_CLK | FPGA_DATA        /* just set outputs */
45
46
47 #define SET_FPGA(data)         immr->im_ioport.iop_pddat = (data)
48 #define GET_FPGA               immr->im_ioport.iop_pddat
49
50 #define FPGA_WRITE_1 {                                                    \
51         SET_FPGA(FPGA_PRG |            FPGA_DATA);  /* set clock to 0 */  \
52         SET_FPGA(FPGA_PRG |            FPGA_DATA);  /* set data to 1  */  \
53         SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);  /* set clock to 1 */  \
54         SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);}     /* set data to 1  */
55
56 #define FPGA_WRITE_0 {                                                    \
57         SET_FPGA(FPGA_PRG |            FPGA_DATA);  /* set clock to 0 */  \
58         SET_FPGA(FPGA_PRG);                         /* set data to 0  */  \
59         SET_FPGA(FPGA_PRG | FPGA_CLK);              /* set clock to 1 */  \
60         SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);}     /* set data to 1  */
61
62
63 int fpga_boot (unsigned char *fpgadata, int size)
64 {
65         volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
66         int i, index, len;
67         int count;
68
69 #ifdef CONFIG_SYS_FPGA_SPARTAN2
70         int j;
71         unsigned char data;
72 #else
73         unsigned char b;
74         int bit;
75 #endif
76
77         debug ("fpga_boot: fpgadata = %p, size = %d\n", fpgadata, size);
78
79         /* display infos on fpgaimage */
80         printf ("FPGA:");
81         index = 15;
82         for (i = 0; i < 4; i++) {
83                 len = fpgadata[index];
84                 printf (" %s", &(fpgadata[index + 1]));
85                 index += len + 3;
86         }
87         printf ("\n");
88
89
90         index = 0;
91
92 #ifdef CONFIG_SYS_FPGA_SPARTAN2
93         /* search for preamble 0xFFFFFFFF */
94         while (1) {
95                 if ((fpgadata[index] == 0xff) && (fpgadata[index + 1] == 0xff)
96                     && (fpgadata[index + 2] == 0xff)
97                     && (fpgadata[index + 3] == 0xff))
98                         break;  /* preamble found */
99                 else
100                         index++;
101         }
102 #else
103         /* search for preamble 0xFF2X */
104         for (index = 0; index < size - 1; index++) {
105                 if ((fpgadata[index] == 0xff)
106                     && ((fpgadata[index + 1] & 0xf0) == 0x30))
107                         break;
108         }
109         index += 2;
110 #endif
111
112         debug ("FPGA: configdata starts at position 0x%x\n", index);
113         debug ("FPGA: length of fpga-data %d\n", size - index);
114
115         /*
116          * Setup port pins for fpga programming
117          */
118         immr->im_ioport.iop_pddir = FPGA_INIT_PDDIR;
119
120         debug ("%s, ", ((GET_FPGA & FPGA_DONE) == 0) ? "NOT DONE" : "DONE");
121         debug ("%s\n", ((GET_FPGA & FPGA_INIT) == 0) ? "NOT INIT" : "INIT");
122
123         /*
124          * Init fpga by asserting and deasserting PROGRAM*
125          */
126         SET_FPGA (FPGA_CLK | FPGA_DATA);
127
128         /* Wait for FPGA init line low */
129         count = 0;
130         while (GET_FPGA & FPGA_INIT) {
131                 udelay (1000);  /* wait 1ms */
132                 /* Check for timeout - 100us max, so use 3ms */
133                 if (count++ > 3) {
134                         debug ("FPGA: Booting failed!\n");
135                         return ERROR_FPGA_PRG_INIT_LOW;
136                 }
137         }
138
139         debug ("%s, ", ((GET_FPGA & FPGA_DONE) == 0) ? "NOT DONE" : "DONE");
140         debug ("%s\n", ((GET_FPGA & FPGA_INIT) == 0) ? "NOT INIT" : "INIT");
141
142         /* deassert PROGRAM* */
143         SET_FPGA (FPGA_PRG | FPGA_CLK | FPGA_DATA);
144
145         /* Wait for FPGA end of init period .  */
146         count = 0;
147         while (!(GET_FPGA & FPGA_INIT)) {
148                 udelay (1000);  /* wait 1ms */
149                 /* Check for timeout */
150                 if (count++ > 3) {
151                         debug ("FPGA: Booting failed!\n");
152                         return ERROR_FPGA_PRG_INIT_HIGH;
153                 }
154         }
155
156         debug ("%s, ", ((GET_FPGA & FPGA_DONE) == 0) ? "NOT DONE" : "DONE");
157         debug ("%s\n", ((GET_FPGA & FPGA_INIT) == 0) ? "NOT INIT" : "INIT");
158
159         debug ("write configuration data into fpga\n");
160         /* write configuration-data into fpga... */
161
162 #ifdef CONFIG_SYS_FPGA_SPARTAN2
163         /*
164          * Load uncompressed image into fpga
165          */
166         for (i = index; i < size; i++) {
167 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
168                 if ((i % 1024) == 0)
169                         printf ("%6d out of %6d\r", i, size);   /* let them know we are alive */
170 #endif
171
172                 data = fpgadata[i];
173                 for (j = 0; j < 8; j++) {
174                         if ((data & 0x80) == 0x80) {
175                                 FPGA_WRITE_1;
176                         } else {
177                                 FPGA_WRITE_0;
178                         }
179                         data <<= 1;
180                 }
181         }
182         /* add some 0xff to the end of the file */
183         for (i = 0; i < 8; i++) {
184                 data = 0xff;
185                 for (j = 0; j < 8; j++) {
186                         if ((data & 0x80) == 0x80) {
187                                 FPGA_WRITE_1;
188                         } else {
189                                 FPGA_WRITE_0;
190                         }
191                         data <<= 1;
192                 }
193         }
194 #else
195         /* send 0xff 0x20 */
196         FPGA_WRITE_1;
197         FPGA_WRITE_1;
198         FPGA_WRITE_1;
199         FPGA_WRITE_1;
200         FPGA_WRITE_1;
201         FPGA_WRITE_1;
202         FPGA_WRITE_1;
203         FPGA_WRITE_1;
204         FPGA_WRITE_0;
205         FPGA_WRITE_0;
206         FPGA_WRITE_1;
207         FPGA_WRITE_0;
208         FPGA_WRITE_0;
209         FPGA_WRITE_0;
210         FPGA_WRITE_0;
211         FPGA_WRITE_0;
212
213         /*
214          ** Bit_DeCompression
215          **   Code 1           .. maxOnes     : n                 '1's followed by '0'
216          **        maxOnes + 1 .. maxOnes + 1 : n - 1             '1's no '0'
217          **        maxOnes + 2 .. 254         : n - (maxOnes + 2) '0's followed by '1'
218          **        255                        :                   '1'
219          */
220
221         for (i = index; i < size; i++) {
222                 b = fpgadata[i];
223                 if ((b >= 1) && (b <= MAX_ONES)) {
224                         for (bit = 0; bit < b; bit++) {
225                                 FPGA_WRITE_1;
226                         }
227                         FPGA_WRITE_0;
228                 } else if (b == (MAX_ONES + 1)) {
229                         for (bit = 1; bit < b; bit++) {
230                                 FPGA_WRITE_1;
231                         }
232                 } else if ((b >= (MAX_ONES + 2)) && (b <= 254)) {
233                         for (bit = 0; bit < (b - (MAX_ONES + 2)); bit++) {
234                                 FPGA_WRITE_0;
235                         }
236                         FPGA_WRITE_1;
237                 } else if (b == 255) {
238                         FPGA_WRITE_1;
239                 }
240         }
241 #endif
242         debug ("\n\n");
243         debug ("%s, ", ((GET_FPGA & FPGA_DONE) == 0) ? "NOT DONE" : "DONE");
244         debug ("%s\n", ((GET_FPGA & FPGA_INIT) == 0) ? "NOT INIT" : "INIT");
245
246         /*
247          * Check if fpga's DONE signal - correctly booted ?
248          */
249
250         /* Wait for FPGA end of programming period .  */
251         count = 0;
252         while (!(GET_FPGA & FPGA_DONE)) {
253                 udelay (1000);  /* wait 1ms */
254                 /* Check for timeout */
255                 if (count++ > 3) {
256                         debug ("FPGA: Booting failed!\n");
257                         return ERROR_FPGA_PRG_DONE;
258                 }
259         }
260
261         debug ("FPGA: Booting successful!\n");
262         return 0;
263 }