]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/hal/arm/xscale/picasso/v2_0/src/xilinx-load.c
Initial revision
[karo-tx-redboot.git] / packages / hal / arm / xscale / picasso / v2_0 / src / xilinx-load.c
1 //==========================================================================
2 //
3 //      xilinx-load.c
4 //
5 //      FPGA support for NMI uEngine picasso
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 2003 Gary Thomas <gary@mind.be>
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
42 //
43 // Author(s):    David Mazur <david@mind.be>
44 // Contributors: gthomas
45 // Date:         2003-02-20
46 // Purpose:      FPGA support
47 // Description:  
48 //
49 //####DESCRIPTIONEND####
50 //
51 //========================================================================*/
52
53 #include <pkgconf/hal.h>
54 #include <pkgconf/system.h>
55 #include CYGBLD_HAL_PLATFORM_H
56 #include CYGHWR_MEMORY_LAYOUT_H
57
58 #include <cyg/infra/cyg_type.h>         // base types
59 #include <cyg/infra/cyg_trac.h>         // tracing macros
60 #include <cyg/infra/cyg_ass.h>          // assertion macros
61 #include <cyg/infra/diag.h>             // diagnostic printing
62
63 #include <cyg/hal/hal_io.h>             // IO macros
64 #include <cyg/hal/hal_if.h>             // calling interface API
65 #include <cyg/hal/hal_arch.h>           // Register state info
66 #include <cyg/hal/hal_diag.h>
67 #include <cyg/hal/hal_intr.h>           // Interrupt names
68 #include <cyg/hal/hal_cache.h>
69 #include <cyg/io/pci_hw.h>
70 #include <cyg/io/pci.h>
71
72 #include <cyg/hal/plx.h>
73
74 #define FPGA_PROG 0x00020000
75 #define FPGA_INIT 0x00000002
76 #define FPGA_DONE 0x00080000
77
78 #define _FPGA_PROG_BASE 0x0c000000
79 #define FPGA_PROG_BASE (*((volatile cyg_uint32 *)(_FPGA_PROG_BASE)))
80
81 #define FPGA_DONE_DRV   0x8
82 #define FPGA_INIT_DRV   0x10
83 #define FPGA_WRITE      0x20
84
85 #define VGA_PROG_CTRL  0x4008
86 #define VGA_PROG_DATA  0x400C
87
88 #define VGA_DONE       0x1
89 #define VGA_INIT       0x2
90 #define VGA_PROG       0x4
91 #define VGA_DONE_DRV   0x8
92 #define VGA_INIT_DRV   0x10
93 #define VGA_WRITE      0x20
94
95
96 #include <cyg/compress/zlib.h>
97
98 extern char _end;
99
100 static z_stream stream;
101
102 #define FEEDBACK_COUNT 16
103 #define ZCHAR_BUF_SIZE 256
104 struct _zchar_info {
105     char  buf[ZCHAR_BUF_SIZE];
106     char *ptr;
107     int   avail;
108     int   feedback;
109     int   total;
110 };
111
112 // Internal allocator for decompression - just use bottom of heap
113 // which will be reclaimed by eCos once the system is initialized
114 static void *
115 _zcalloc(void *opaque, unsigned int items, unsigned int size)
116 {
117     static char *ptr = (char *)&_end;
118     char *res = ptr;
119
120 //    diag_printf("%s(%p,%d,%d) = %p\n", __FUNCTION__, opaque, items, size, res);
121     ptr += (size*items);
122     return res;
123 }
124
125 static void 
126 _zcfree(void *opaque, void *ptr)
127 {
128 //    diag_printf("%s(%p,%p)\n", __FUNCTION__, opaque, ptr);    
129 }
130
131 static int
132 _zchar(void)
133 {
134     int err;
135     struct _zchar_info *info = (struct _zchar_info *)stream.opaque;
136     static char spin[] = "|/-\\|-";
137     static int tick = 0;
138
139     if (info->avail == 0) {
140         stream.next_out = info->buf;
141         stream.avail_out = sizeof(info->buf);
142         info->ptr = info->buf;
143         err = inflate(&stream, Z_SYNC_FLUSH);
144         info->avail = (char *)stream.next_out - info->buf;
145         if (--info->feedback == 0) {
146             diag_printf("%c\b", spin[tick++]);
147             if (tick >= (sizeof(spin)-1)) {
148                 tick = 0;
149             }
150             info->feedback = FEEDBACK_COUNT;
151         }
152     }
153     if (info->avail) {
154         info->avail--;
155         info->total++;
156         return *(info->ptr)++;
157     } else {
158         // End of data stream
159         return -1;
160     }
161 }
162
163 /**
164  * A little bit swapping function, necessary due to the xilinx bit file format.
165  */
166 static const cyg_uint8 _swapped[] = {
167     0x00, 0x08, 0x04, 0x0C, 0x02, 0x0A, 0x06, 0x0E,
168     0x01, 0x09, 0x05, 0x0D, 0x03, 0x0B, 0x07, 0x0F
169 };
170
171 static cyg_uint8 
172 bitswap(cyg_uint8 byte)
173 {
174     cyg_uint8 _new = (_swapped[byte & 0x0F] << 4) | (_swapped[(byte >> 4) & 0x0F]);
175     return _new;
176 }
177
178 typedef int _bitfile_fun(void);
179 typedef void _download_fun(_bitfile_fun *_bitfile);
180
181 /**
182  * Gets the tag at given location in the bitfile.
183  */
184 static cyg_uint8 
185 bitfile_get_tag(_bitfile_fun *_bitfile)
186 {
187     return (*_bitfile)();
188 }
189
190 static cyg_uint16 
191 bitfile_get_len16(_bitfile_fun *_bitfile)
192 {
193     cyg_uint16 length;
194
195     length = (*_bitfile)() << 8;
196     length |= (*_bitfile)();
197
198     return length;
199 }
200
201 static int 
202 bitfile_get_len32(_bitfile_fun *_bitfile)
203 {
204     cyg_uint32 length;
205
206     length = (*_bitfile)() << 24;
207     length |= (*_bitfile)() << 16;
208     length |= (*_bitfile)() << 8;
209     length |= (*_bitfile)();
210
211     return length;
212 }
213
214 /**
215  * Process a string tag.
216  */
217 static void 
218 bitfile_process_string_tag(char *description, _bitfile_fun *_bitfile)
219 {
220     int len,i;
221
222     len = bitfile_get_len16(_bitfile);
223     diag_printf(description);
224     for (i = 0; i < len; i++) {
225         diag_printf("%c", (*_bitfile)());
226     }
227 }
228
229 /**
230  * Process the 'e' tag in the bit file, which is the actual code that is to
231  * be programmed on the fpga.
232  */
233 static void 
234 bitfile_process_tag_e(_bitfile_fun *_bitfile)
235 {
236     int len,count,i;
237     cyg_uint8 byte;
238     cyg_uint32 word;
239
240     len = bitfile_get_len32(_bitfile);
241
242     *PXA2X0_GPCR0 = FPGA_PROG;
243
244     for (count=0; count<10000; count++)
245         if ((*PXA2X0_GPLR0 & FPGA_INIT) == 0)
246             break;
247     if ((*PXA2X0_GPLR0 & FPGA_INIT) != 0)
248         diag_printf("INIT did not go low. FPGA programming failed\n");
249
250     *PXA2X0_GPSR0 = FPGA_PROG;
251
252     for (count=0; count<10000; count++)
253         if ((*PXA2X0_GPLR0 & FPGA_INIT) != 0)
254             break;
255     if ((*PXA2X0_GPLR0 & FPGA_INIT) == 0)
256         diag_printf("INIT did not go high. FPGA programming failed\n");
257
258     for( i=0; i<len; i++) {
259         if ((*PXA2X0_GPLR0 & FPGA_INIT) == 0) {
260             diag_printf("CRC Error. FPGA programming failed\n");
261         }
262
263         byte = (*_bitfile)();
264         word = 0;
265
266         if (byte & (0x01 << 7)) word|=(0x01);
267         if (byte & (0x01 << 6)) word|=(0x01 << 18);
268         if (byte & (0x01 << 5)) word|=(0x01 << 14);
269         if (byte & (0x01 << 4)) word|=(0x01 << 1);
270         if (byte & (0x01 << 3)) word|=(0x01 << 4);
271         if (byte & (0x01 << 2)) word|=(0x01 << 6);
272         if (byte & (0x01 << 1)) word|=(0x01 << 9);
273         if (byte & (0x01)) word|=(0x01 << 30);
274
275         FPGA_PROG_BASE = word;
276     }
277
278     for (count=0; count<10000; count++)
279         if ((*PXA2X0_GPLR0 & FPGA_DONE) != 0)
280             break;
281     if ((*PXA2X0_GPLR0 & FPGA_DONE) == 0)
282         diag_printf("DONE did not go high. FPGA programming failed\n");
283
284 }
285
286 /**
287  * Process the 'e' tag in the bit file, which is the actual code that is to
288  * be programmed on the fpga.
289  */
290 static void 
291 vga_bitfile_process_tag_e(_bitfile_fun *_bitfile)
292 {
293     int len,count,i;
294     cyg_uint8 byte;
295
296     len = bitfile_get_len32(_bitfile);
297
298     localbus_writeb(VGA_WRITE,  VGA_PROG_CTRL);
299     localbus_writeb(VGA_WRITE | VGA_PROG,  VGA_PROG_CTRL);
300
301     for (count=0; count<10000; count++)
302         if (localbus_readb(VGA_PROG_CTRL) & VGA_INIT)
303             break;
304     if (!(localbus_readb(VGA_PROG_CTRL) & VGA_INIT))
305         diag_printf("INIT did not go high. VGA FPGA programming failed\n");
306
307     localbus_writeb(VGA_PROG, VGA_PROG_CTRL);
308
309     for (i=0; i<len; i++) {
310         byte = (*_bitfile)();
311         localbus_writeb(bitswap(byte),VGA_PROG_DATA);
312     } 
313
314     for (count=0; count<10000; count++)
315         if (localbus_readb(VGA_PROG_CTRL) & VGA_DONE)
316             break;
317     if (!(localbus_readb(VGA_PROG_CTRL) & VGA_DONE))
318         diag_printf("DONE did not go high. VGA FPGA programming failed\n");
319
320     localbus_writeb(VGA_PROG | VGA_WRITE,  VGA_PROG_CTRL);
321 }
322
323 //
324 // Download a bitstream
325 //
326 static void
327 download_bitstream(char *title, _bitfile_fun *_bitfile, _download_fun *_download)
328 {
329     int len, tag;
330
331     diag_printf("Load %s(", title);
332
333     len = bitfile_get_len16(_bitfile);
334     while (len-- > 0) {
335         (*_bitfile)();  // Skip
336     }
337     len = bitfile_get_len16(_bitfile);
338
339     tag = 0;
340     while (tag != 'e') {
341
342         tag = bitfile_get_tag(_bitfile);
343         switch (tag) {
344         case 'a':
345             bitfile_process_string_tag("Design:", _bitfile);
346             break;
347
348         case 'b':
349             bitfile_process_string_tag(", Part:", _bitfile);
350             break;
351
352         case 'c':
353             bitfile_process_string_tag(", Date:", _bitfile);
354             break;
355
356         case 'd':
357             bitfile_process_string_tag(" ", _bitfile);
358             break;
359
360         case 'e':
361             (*_download)(_bitfile);
362             break;
363
364         default:
365             diag_printf("Unknown tag. aborting...\n");
366             return;
367         }
368     }
369 }
370
371
372 /**
373  * Process a bitfile located at the given address.
374  */
375 void 
376 load_fpga(cyg_uint8 *compressed_bitfile, int len) 
377 {
378     int err;
379     struct _zchar_info zchar_data;
380
381     stream.zalloc = _zcalloc;
382     stream.zfree = _zcfree;
383     stream.next_in = compressed_bitfile;
384     stream.avail_in = len;
385     stream.next_out = 0;
386     stream.avail_out = 0;
387     stream.opaque = (void *)&zchar_data;
388     zchar_data.avail = 0;
389     zchar_data.feedback = FEEDBACK_COUNT;
390     zchar_data.total = 0;
391     err = inflateInit(&stream);
392     if (err) {
393         diag_printf("%s: Can't init stream\n", __FUNCTION__);
394         return;
395     }
396     // Set up to download FPGA bitstreap
397     *PXA2X0_GPSR0 = FPGA_PROG;
398     download_bitstream("PCI ctlr", _zchar, bitfile_process_tag_e);
399     inflateEnd(&stream);
400     diag_printf(") %x bytes\n", zchar_data.total);
401 }
402
403 #if 0
404 /**
405  * Process a bitfile located at the given address.
406  */
407 void 
408 load_vga(cyg_uint8 *compressed_bitfile, int len)
409 {
410     int err;
411     struct _zchar_info zchar_data;
412
413     stream.zalloc = _zcalloc;
414     stream.zfree = _zcfree;
415     stream.next_in = compressed_bitfile;
416     stream.avail_in = len;
417     stream.next_out = 0;
418     stream.avail_out = 0;
419     stream.opaque = (void *)&zchar_data;
420     zchar_data.avail = 0;
421     zchar_data.feedback = FEEDBACK_COUNT;
422     zchar_data.total = 0;
423     err = inflateInit(&stream);
424     if (err) {
425         diag_printf("%s: Can't init stream\n", __FUNCTION__);
426         return;
427     }
428     download_bitstream("VGA ctlr", _zchar, vga_bitfile_process_tag_e);
429     inflateEnd(&stream);
430     diag_printf(") %x bytes\n", zchar_data.total);
431 }
432 #endif
433