]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/esd/common/fpga.c
rename CFG_ macros to CONFIG_SYS
[karo-tx-uboot.git] / board / esd / common / fpga.c
1 /*
2  * (C) Copyright 2001-2004
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
25 #include <common.h>
26 #include <asm/processor.h>
27 #include <command.h>
28
29 /* ------------------------------------------------------------------------- */
30
31 #ifdef FPGA_DEBUG
32 #define DBG(x...) printf(x)
33 #else
34 #define DBG(x...)
35 #endif /* DEBUG */
36
37 #define MAX_ONES               226
38
39 #ifdef CONFIG_SYS_FPGA_PRG
40 # define FPGA_PRG              CONFIG_SYS_FPGA_PRG      /* FPGA program pin (ppc output) */
41 # define FPGA_CLK              CONFIG_SYS_FPGA_CLK      /* FPGA clk pin (ppc output)    */
42 # define FPGA_DATA             CONFIG_SYS_FPGA_DATA     /* FPGA data pin (ppc output)  */
43 # define FPGA_DONE             CONFIG_SYS_FPGA_DONE     /* FPGA done pin (ppc input)   */
44 # define FPGA_INIT             CONFIG_SYS_FPGA_INIT     /* FPGA init pin (ppc input)   */
45 #else
46 # define FPGA_PRG              0x04000000       /* FPGA program pin (ppc output) */
47 # define FPGA_CLK              0x02000000       /* FPGA clk pin (ppc output)     */
48 # define FPGA_DATA             0x01000000       /* FPGA data pin (ppc output)    */
49 # define FPGA_DONE             0x00800000       /* FPGA done pin (ppc input)     */
50 # define FPGA_INIT             0x00400000       /* FPGA init pin (ppc input)     */
51 #endif
52
53 #define ERROR_FPGA_PRG_INIT_LOW  -1     /* Timeout after PRG* asserted   */
54 #define ERROR_FPGA_PRG_INIT_HIGH -2     /* Timeout after PRG* deasserted */
55 #define ERROR_FPGA_PRG_DONE      -3     /* Timeout after programming     */
56
57 #ifndef SET_FPGA
58 # define SET_FPGA(data)         out32(GPIO0_OR, data)
59 #endif
60
61 #ifdef FPGA_PROG_ACTIVE_HIGH
62 # define FPGA_PRG_LOW           FPGA_PRG
63 # define FPGA_PRG_HIGH          0
64 #else
65 # define FPGA_PRG_LOW           0
66 # define FPGA_PRG_HIGH          FPGA_PRG
67 #endif
68
69 #define FPGA_CLK_LOW            0
70 #define FPGA_CLK_HIGH           FPGA_CLK
71
72 #define FPGA_DATA_LOW           0
73 #define FPGA_DATA_HIGH          FPGA_DATA
74
75 #define FPGA_WRITE_1 {                                                                   \
76         SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_LOW  | FPGA_DATA_HIGH);  /* set clock to 0 */  \
77         SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_LOW  | FPGA_DATA_HIGH);  /* set data to 1  */  \
78         SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_HIGH | FPGA_DATA_HIGH);  /* set clock to 1 */  \
79         SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_HIGH | FPGA_DATA_HIGH);}      /* set data to 1  */
80
81 #define FPGA_WRITE_0 {                                                    \
82         SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_LOW  | FPGA_DATA_HIGH);  /* set clock to 0 */  \
83         SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_LOW  | FPGA_DATA_LOW);   /* set data to 0  */  \
84         SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_HIGH | FPGA_DATA_LOW);   /* set clock to 1 */  \
85         SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_HIGH | FPGA_DATA_HIGH);}      /* set data to 1  */
86
87 #ifndef FPGA_DONE_STATE
88 # define FPGA_DONE_STATE (in32(GPIO0_IR) & FPGA_DONE)
89 #endif
90 #ifndef FPGA_INIT_STATE
91 # define FPGA_INIT_STATE (in32(GPIO0_IR) & FPGA_INIT)
92 #endif
93
94
95 static int fpga_boot (const unsigned char *fpgadata, int size)
96 {
97         int i, index, len;
98         int count;
99         unsigned char b;
100
101 #ifdef CONFIG_SYS_FPGA_SPARTAN2
102         int j;
103 #else
104         int bit;
105 #endif
106
107         /* display infos on fpgaimage */
108         index = 15;
109         for (i = 0; i < 4; i++) {
110                 len = fpgadata[index];
111                 DBG ("FPGA: %s\n", &(fpgadata[index + 1]));
112                 index += len + 3;
113         }
114
115 #ifdef CONFIG_SYS_FPGA_SPARTAN2
116         /* search for preamble 0xFFFFFFFF */
117         while (1) {
118                 if ((fpgadata[index] == 0xff) && (fpgadata[index + 1] == 0xff)
119                     && (fpgadata[index + 2] == 0xff)
120                     && (fpgadata[index + 3] == 0xff))
121                         break;  /* preamble found */
122                 else
123                         index++;
124         }
125 #else
126         /* search for preamble 0xFF2X */
127         for (index = 0; index < size - 1; index++) {
128                 if ((fpgadata[index] == 0xff)
129                     && ((fpgadata[index + 1] & 0xf0) == 0x30))
130                         break;
131         }
132         index += 2;
133 #endif
134
135         DBG ("FPGA: configdata starts at position 0x%x\n", index);
136         DBG ("FPGA: length of fpga-data %d\n", size - index);
137
138         /*
139          * Setup port pins for fpga programming
140          */
141 #ifndef CONFIG_M5249
142         out32 (GPIO0_ODR, 0x00000000);  /* no open drain pins */
143         out32 (GPIO0_TCR, in32 (GPIO0_TCR) | FPGA_PRG | FPGA_CLK | FPGA_DATA);  /* setup for output */
144 #endif
145         SET_FPGA (FPGA_PRG_HIGH | FPGA_CLK_HIGH | FPGA_DATA_HIGH);      /* set pins to high */
146
147         DBG ("%s, ", (FPGA_DONE_STATE == 0) ? "NOT DONE" : "DONE");
148         DBG ("%s\n", (FPGA_INIT_STATE == 0) ? "NOT INIT" : "INIT");
149
150         /*
151          * Init fpga by asserting and deasserting PROGRAM*
152          */
153         SET_FPGA (FPGA_PRG_LOW | FPGA_CLK_HIGH | FPGA_DATA_HIGH);       /* set prog active */
154
155         /* Wait for FPGA init line low */
156         count = 0;
157         while (FPGA_INIT_STATE) {
158                 udelay (1000);  /* wait 1ms */
159                 /* Check for timeout - 100us max, so use 3ms */
160                 if (count++ > 3) {
161                         DBG ("FPGA: Booting failed!\n");
162                         return ERROR_FPGA_PRG_INIT_LOW;
163                 }
164         }
165
166         DBG ("%s, ", (FPGA_DONE_STATE == 0) ? "NOT DONE" : "DONE");
167         DBG ("%s\n", (FPGA_INIT_STATE == 0) ? "NOT INIT" : "INIT");
168
169         /* deassert PROGRAM* */
170         SET_FPGA (FPGA_PRG_HIGH | FPGA_CLK_HIGH | FPGA_DATA_HIGH);      /* set prog inactive */
171
172         /* Wait for FPGA end of init period .  */
173         count = 0;
174         while (!(FPGA_INIT_STATE)) {
175                 udelay (1000);  /* wait 1ms */
176                 /* Check for timeout */
177                 if (count++ > 3) {
178                         DBG ("FPGA: Booting failed!\n");
179                         return ERROR_FPGA_PRG_INIT_HIGH;
180                 }
181         }
182
183         DBG ("%s, ", (FPGA_DONE_STATE == 0) ? "NOT DONE" : "DONE");
184         DBG ("%s\n", (FPGA_INIT_STATE == 0) ? "NOT INIT" : "INIT");
185
186         DBG ("write configuration data into fpga\n");
187         /* write configuration-data into fpga... */
188
189 #ifdef CONFIG_SYS_FPGA_SPARTAN2
190         /*
191          * Load uncompressed image into fpga
192          */
193         for (i = index; i < size; i++) {
194                 b = fpgadata[i];
195                 for (j = 0; j < 8; j++) {
196                         if ((b & 0x80) == 0x80) {
197                                 FPGA_WRITE_1;
198                         } else {
199                                 FPGA_WRITE_0;
200                         }
201                         b <<= 1;
202                 }
203         }
204 #else
205         /* send 0xff 0x20 */
206         FPGA_WRITE_1;
207         FPGA_WRITE_1;
208         FPGA_WRITE_1;
209         FPGA_WRITE_1;
210         FPGA_WRITE_1;
211         FPGA_WRITE_1;
212         FPGA_WRITE_1;
213         FPGA_WRITE_1;
214         FPGA_WRITE_0;
215         FPGA_WRITE_0;
216         FPGA_WRITE_1;
217         FPGA_WRITE_0;
218         FPGA_WRITE_0;
219         FPGA_WRITE_0;
220         FPGA_WRITE_0;
221         FPGA_WRITE_0;
222
223         /*
224          ** Bit_DeCompression
225          **   Code 1           .. maxOnes     : n                 '1's followed by '0'
226          **        maxOnes + 1 .. maxOnes + 1 : n - 1             '1's no '0'
227          **        maxOnes + 2 .. 254         : n - (maxOnes + 2) '0's followed by '1'
228          **        255                        :                   '1'
229          */
230
231         for (i = index; i < size; i++) {
232                 b = fpgadata[i];
233                 if ((b >= 1) && (b <= MAX_ONES)) {
234                         for (bit = 0; bit < b; bit++) {
235                                 FPGA_WRITE_1;
236                         }
237                         FPGA_WRITE_0;
238                 } else if (b == (MAX_ONES + 1)) {
239                         for (bit = 1; bit < b; bit++) {
240                                 FPGA_WRITE_1;
241                         }
242                 } else if ((b >= (MAX_ONES + 2)) && (b <= 254)) {
243                         for (bit = 0; bit < (b - (MAX_ONES + 2)); bit++) {
244                                 FPGA_WRITE_0;
245                         }
246                         FPGA_WRITE_1;
247                 } else if (b == 255) {
248                         FPGA_WRITE_1;
249                 }
250         }
251 #endif
252
253         DBG ("%s, ", (FPGA_DONE_STATE == 0) ? "NOT DONE" : "DONE");
254         DBG ("%s\n", (FPGA_INIT_STATE == 0) ? "NOT INIT" : "INIT");
255
256         /*
257          * Check if fpga's DONE signal - correctly booted ?
258          */
259
260         /* Wait for FPGA end of programming period .  */
261         count = 0;
262         while (!(FPGA_DONE_STATE)) {
263                 udelay (1000);  /* wait 1ms */
264                 /* Check for timeout */
265                 if (count++ > 3) {
266                         DBG ("FPGA: Booting failed!\n");
267                         return ERROR_FPGA_PRG_DONE;
268                 }
269         }
270
271         DBG ("FPGA: Booting successful!\n");
272         return 0;
273 }