Merge branch 'master' of /home/stefan/git/u-boot/u-boot
[platform/kernel/u-boot.git] / common / fpga.c
1 /*
2  * (C) Copyright 2002
3  * Rich Ireland, Enterasys Networks, rireland@enterasys.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
25 /*
26  *  Generic FPGA support
27  */
28 #include <common.h>             /* core U-Boot definitions */
29 #include <xilinx.h>             /* xilinx specific definitions */
30 #include <altera.h>             /* altera specific definitions */
31
32 #if defined(CONFIG_FPGA)
33
34 #if 0
35 #define FPGA_DEBUG              /* define FPGA_DEBUG to get debug messages */
36 #endif
37
38 /* Local definitions */
39 #ifndef CONFIG_MAX_FPGA_DEVICES
40 #define CONFIG_MAX_FPGA_DEVICES         5
41 #endif
42
43 /* Enable/Disable debug console messages */
44 #ifdef FPGA_DEBUG
45 #define PRINTF(fmt,args...)     printf (fmt ,##args)
46 #else
47 #define PRINTF(fmt,args...)
48 #endif
49
50 /* Local static data */
51 static ulong relocation_offset = 0;
52 static int next_desc = FPGA_INVALID_DEVICE;
53 static fpga_desc desc_table[CONFIG_MAX_FPGA_DEVICES];
54
55 /* Local static functions */
56 static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_get_desc( int devnum );
57 static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_validate( int devnum, void *buf,
58                                          size_t bsize, char *fn );
59 static int fpga_dev_info( int devnum );
60
61
62 /* ------------------------------------------------------------------------- */
63
64 /* fpga_no_sup
65  * 'no support' message function
66  */
67 static void fpga_no_sup( char *fn, char *msg )
68 {
69         if ( fn && msg ) {
70                 printf( "%s: No support for %s.\n", fn, msg);
71         } else if ( msg ) {
72                 printf( "No support for %s.\n", msg);
73         } else {
74                 printf( "No FPGA suport!\n");
75         }
76 }
77
78
79 /* fpga_get_desc
80  *      map a device number to a descriptor
81  */
82 static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_get_desc( int devnum )
83 {
84         fpga_desc *desc = (fpga_desc * )NULL;
85
86         if (( devnum >= 0 ) && (devnum < next_desc )) {
87                 desc = &desc_table[devnum];
88                 PRINTF( "%s: found fpga descriptor #%d @ 0x%p\n",
89                                 __FUNCTION__, devnum, desc );
90         }
91
92         return desc;
93 }
94
95
96 /* fpga_validate
97  *      generic parameter checking code
98  */
99 static __attribute__((__const__)) fpga_desc * __attribute__((__const__)) fpga_validate( int devnum, void *buf,
100                                          size_t bsize, char *fn )
101 {
102         fpga_desc * desc = fpga_get_desc( devnum );
103
104         if ( !desc ) {
105                 printf( "%s: Invalid device number %d\n", fn, devnum );
106         }
107
108         if ( !buf ) {
109                 printf( "%s: Null buffer.\n", fn );
110                 return (fpga_desc * const)NULL;
111         }
112         return desc;
113 }
114
115
116 /* fpga_dev_info
117  *      generic multiplexing code
118  */
119 static int fpga_dev_info( int devnum )
120 {
121         int ret_val = FPGA_FAIL;           /* assume failure */
122         const fpga_desc * const desc = fpga_get_desc( devnum );
123
124         if ( desc ) {
125                 PRINTF( "%s: Device Descriptor @ 0x%p\n",
126                                 __FUNCTION__, desc->devdesc );
127
128                 switch ( desc->devtype ) {
129                 case fpga_xilinx:
130 #if defined(CONFIG_FPGA_XILINX)
131                         printf( "Xilinx Device\nDescriptor @ 0x%p\n", desc );
132                         ret_val = xilinx_info( desc->devdesc );
133 #else
134                         fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" );
135 #endif
136                         break;
137                 case fpga_altera:
138 #if defined(CONFIG_FPGA_ALTERA)
139                         printf( "Altera Device\nDescriptor @ 0x%p\n", desc );
140                         ret_val = altera_info( desc->devdesc );
141 #else
142                         fpga_no_sup( (char *)__FUNCTION__, "Altera devices" );
143 #endif
144                         break;
145                 default:
146                         printf( "%s: Invalid or unsupported device type %d\n",
147                                         __FUNCTION__, desc->devtype );
148                 }
149         } else {
150                 printf( "%s: Invalid device number %d\n",
151                         __FUNCTION__, devnum );
152         }
153
154         return ret_val;
155 }
156
157
158 /* fpga_reloc
159  *      generic multiplexing code
160  */
161 int fpga_reloc( fpga_type devtype, void *desc, ulong reloc_off )
162 {
163         int ret_val = FPGA_FAIL;
164
165         PRINTF( "%s: Relocating Device of type %d @ 0x%p with offset %lx\n",
166                                 __FUNCTION__, devtype, desc, reloc_off );
167
168         switch ( devtype ) {
169         case fpga_xilinx:
170 #if defined(CONFIG_FPGA_XILINX)
171                 ret_val = xilinx_reloc( desc, reloc_off );
172 #else
173                 fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" );
174 #endif
175                 break;
176         case fpga_altera:
177 #if defined(CONFIG_FPGA_ALTERA)
178                 ret_val = altera_reloc( desc, reloc_off );
179 #else
180                 fpga_no_sup( (char *)__FUNCTION__, "Altera devices" );
181 #endif
182                 break;
183         default:
184                 printf( "%s: Invalid or unsupported device type %d\n",
185                         __FUNCTION__, devtype );
186         }
187
188         return ret_val;
189 }
190
191 /* ------------------------------------------------------------------------- */
192 /* fgpa_init is usually called from misc_init_r() and MUST be called
193  * before any of the other fpga functions are used.
194  */
195 void fpga_init( ulong reloc_off )
196 {
197         relocation_offset = reloc_off;
198         next_desc = 0;
199         memset( desc_table, 0, sizeof(desc_table));
200
201         PRINTF( "%s: CONFIG_FPGA = 0x%x\n", __FUNCTION__, CONFIG_FPGA );
202 }
203
204 /* fpga_count
205  * Basic interface function to get the current number of devices available.
206  */
207 int fpga_count( void )
208 {
209         return next_desc;
210 }
211
212 /* fpga_add
213  *      Attempts to relocate the device/board specific interface code
214  *      to the proper RAM locations and adds the device descriptor to
215  *      the device table.
216  */
217 int fpga_add( fpga_type devtype, void *desc )
218 {
219         int devnum = FPGA_INVALID_DEVICE;
220
221         if ( next_desc  < 0 ) {
222                 printf( "%s: FPGA support not initialized!\n", __FUNCTION__ );
223         } else if (( devtype > fpga_min_type ) && ( devtype < fpga_undefined )) {
224                 if ( desc ) {
225                         if ( next_desc < CONFIG_MAX_FPGA_DEVICES ) {
226                                 if ( fpga_reloc( devtype, desc, relocation_offset )
227                                   == FPGA_SUCCESS ) {
228                                         devnum = next_desc;
229                                         desc_table[next_desc].devtype = devtype;
230                                         desc_table[next_desc++].devdesc = desc;
231                                 } else {
232                                         printf( "%s: Unable to relocate device interface table!\n",
233                                                 __FUNCTION__ );
234                                 }
235                         } else {
236                                 printf( "%s: Exceeded Max FPGA device count\n", __FUNCTION__ );
237                         }
238                 } else {
239                         printf( "%s: NULL device descriptor\n", __FUNCTION__ );
240                 }
241         } else {
242                 printf( "%s: Unsupported FPGA type %d\n", __FUNCTION__, devtype );
243         }
244
245         return devnum;
246 }
247
248 /*
249  *      Generic multiplexing code
250  */
251 int fpga_load( int devnum, void *buf, size_t bsize )
252 {
253         int ret_val = FPGA_FAIL;           /* assume failure */
254         fpga_desc * desc = fpga_validate( devnum, buf, bsize, (char *)__FUNCTION__ );
255
256         if ( desc ) {
257                 switch ( desc->devtype ) {
258                 case fpga_xilinx:
259 #if defined(CONFIG_FPGA_XILINX)
260                         ret_val = xilinx_load( desc->devdesc, buf, bsize );
261 #else
262                         fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" );
263 #endif
264                         break;
265                 case fpga_altera:
266 #if defined(CONFIG_FPGA_ALTERA)
267                         ret_val = altera_load( desc->devdesc, buf, bsize );
268 #else
269                         fpga_no_sup( (char *)__FUNCTION__, "Altera devices" );
270 #endif
271                         break;
272                 default:
273                         printf( "%s: Invalid or unsupported device type %d\n",
274                                 __FUNCTION__, desc->devtype );
275                 }
276         }
277
278         return ret_val;
279 }
280
281 /* fpga_dump
282  *      generic multiplexing code
283  */
284 int fpga_dump( int devnum, void *buf, size_t bsize )
285 {
286         int ret_val = FPGA_FAIL;           /* assume failure */
287         fpga_desc * desc = fpga_validate( devnum, buf, bsize, (char *)__FUNCTION__ );
288
289         if ( desc ) {
290                 switch ( desc->devtype ) {
291                 case fpga_xilinx:
292 #if defined(CONFIG_FPGA_XILINX)
293                         ret_val = xilinx_dump( desc->devdesc, buf, bsize );
294 #else
295                         fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" );
296 #endif
297                         break;
298                 case fpga_altera:
299 #if defined(CONFIG_FPGA_ALTERA)
300                         ret_val = altera_dump( desc->devdesc, buf, bsize );
301 #else
302                         fpga_no_sup( (char *)__FUNCTION__, "Altera devices" );
303 #endif
304                         break;
305                 default:
306                         printf( "%s: Invalid or unsupported device type %d\n",
307                                 __FUNCTION__, desc->devtype );
308                 }
309         }
310
311         return ret_val;
312 }
313
314
315 /* fpga_info
316  *      front end to fpga_dev_info.  If devnum is invalid, report on all
317  *      available devices.
318  */
319 int fpga_info( int devnum )
320 {
321         if ( devnum == FPGA_INVALID_DEVICE ) {
322                 if ( next_desc > 0 ) {
323                         int dev;
324
325                         for ( dev = 0; dev < next_desc; dev++ ) {
326                                 fpga_dev_info( dev );
327                         }
328                         return FPGA_SUCCESS;
329                 } else {
330                         printf( "%s: No FPGA devices available.\n", __FUNCTION__ );
331                         return FPGA_FAIL;
332                 }
333         }
334         else return fpga_dev_info( devnum );
335 }
336
337 /* ------------------------------------------------------------------------- */
338
339 #endif  /* CONFIG_FPGA */