Merge branch 'master' of /home/wd/git/u-boot/master/
[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 #if 0
203         PRINTF( "%s: CFG_FPGA_XILINX = 0x%x\n", __FUNCTION__, CFG_FPGA_XILINX );
204         PRINTF( "%s: CFG_FPGA_ALTERA = 0x%x\n", __FUNCTION__, CFG_FPGA_ALTERA );
205 #endif
206 }
207
208 /* fpga_count
209  * Basic interface function to get the current number of devices available.
210  */
211 int fpga_count( void )
212 {
213         return next_desc;
214 }
215
216 /* fpga_add
217  *      Attempts to relocate the device/board specific interface code
218  *      to the proper RAM locations and adds the device descriptor to
219  *      the device table.
220  */
221 int fpga_add( fpga_type devtype, void *desc )
222 {
223         int devnum = FPGA_INVALID_DEVICE;
224
225         if ( next_desc  < 0 ) {
226                 printf( "%s: FPGA support not initialized!\n", __FUNCTION__ );
227         } else if (( devtype > fpga_min_type ) && ( devtype < fpga_undefined )) {
228                 if ( desc ) {
229                         if ( next_desc < CONFIG_MAX_FPGA_DEVICES ) {
230                                 if ( fpga_reloc( devtype, desc, relocation_offset )
231                                   == FPGA_SUCCESS ) {
232                                         devnum = next_desc;
233                                         desc_table[next_desc].devtype = devtype;
234                                         desc_table[next_desc++].devdesc = desc;
235                                 } else {
236                                         printf( "%s: Unable to relocate device interface table!\n",
237                                                 __FUNCTION__ );
238                                 }
239                         } else {
240                                 printf( "%s: Exceeded Max FPGA device count\n", __FUNCTION__ );
241                         }
242                 } else {
243                         printf( "%s: NULL device descriptor\n", __FUNCTION__ );
244                 }
245         } else {
246                 printf( "%s: Unsupported FPGA type %d\n", __FUNCTION__, devtype );
247         }
248
249         return devnum;
250 }
251
252 /*
253  *      Generic multiplexing code
254  */
255 int fpga_load( int devnum, void *buf, size_t bsize )
256 {
257         int ret_val = FPGA_FAIL;           /* assume failure */
258         fpga_desc * desc = fpga_validate( devnum, buf, bsize, (char *)__FUNCTION__ );
259
260         if ( desc ) {
261                 switch ( desc->devtype ) {
262                 case fpga_xilinx:
263 #if defined(CONFIG_FPGA_XILINX)
264                         ret_val = xilinx_load( desc->devdesc, buf, bsize );
265 #else
266                         fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" );
267 #endif
268                         break;
269                 case fpga_altera:
270 #if defined(CONFIG_FPGA_ALTERA)
271                         ret_val = altera_load( desc->devdesc, buf, bsize );
272 #else
273                         fpga_no_sup( (char *)__FUNCTION__, "Altera devices" );
274 #endif
275                         break;
276                 default:
277                         printf( "%s: Invalid or unsupported device type %d\n",
278                                 __FUNCTION__, desc->devtype );
279                 }
280         }
281
282         return ret_val;
283 }
284
285 /* fpga_dump
286  *      generic multiplexing code
287  */
288 int fpga_dump( int devnum, void *buf, size_t bsize )
289 {
290         int ret_val = FPGA_FAIL;           /* assume failure */
291         fpga_desc * desc = fpga_validate( devnum, buf, bsize, (char *)__FUNCTION__ );
292
293         if ( desc ) {
294                 switch ( desc->devtype ) {
295                 case fpga_xilinx:
296 #if defined(CONFIG_FPGA_XILINX)
297                         ret_val = xilinx_dump( desc->devdesc, buf, bsize );
298 #else
299                         fpga_no_sup( (char *)__FUNCTION__, "Xilinx devices" );
300 #endif
301                         break;
302                 case fpga_altera:
303 #if defined(CONFIG_FPGA_ALTERA)
304                         ret_val = altera_dump( desc->devdesc, buf, bsize );
305 #else
306                         fpga_no_sup( (char *)__FUNCTION__, "Altera devices" );
307 #endif
308                         break;
309                 default:
310                         printf( "%s: Invalid or unsupported device type %d\n",
311                                 __FUNCTION__, desc->devtype );
312                 }
313         }
314
315         return ret_val;
316 }
317
318
319 /* fpga_info
320  *      front end to fpga_dev_info.  If devnum is invalid, report on all
321  *      available devices.
322  */
323 int fpga_info( int devnum )
324 {
325         if ( devnum == FPGA_INVALID_DEVICE ) {
326                 if ( next_desc > 0 ) {
327                         int dev;
328
329                         for ( dev = 0; dev < next_desc; dev++ ) {
330                                 fpga_dev_info( dev );
331                         }
332                         return FPGA_SUCCESS;
333                 } else {
334                         printf( "%s: No FPGA devices available.\n", __FUNCTION__ );
335                         return FPGA_FAIL;
336                 }
337         }
338         else return fpga_dev_info( devnum );
339 }
340
341 /* ------------------------------------------------------------------------- */
342
343 #endif  /* CONFIG_FPGA */