Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / 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  * SPDX-License-Identifier:     GPL-2.0+
7  */
8 /* The DEBUG define must be before common to enable debugging */
9 #undef DEBUG
10 #include <common.h>
11 #include <asm/processor.h>
12 #include <command.h>
13 #include "fpga.h"
14 /* ------------------------------------------------------------------------- */
15
16 #define MAX_ONES               226
17
18 /* MPC850 port D */
19 #define PD(bit) (1 << (15 - (bit)))
20 # define FPGA_INIT             PD(11)   /* FPGA init pin (ppc input)     */
21 # define FPGA_PRG              PD(12)   /* FPGA program pin (ppc output) */
22 # define FPGA_CLK              PD(13)   /* FPGA clk pin (ppc output)     */
23 # define FPGA_DATA             PD(14)   /* FPGA data pin (ppc output)    */
24 # define FPGA_DONE             PD(15)   /* FPGA done pin (ppc input)     */
25
26
27 /* DDR 0 - input, 1 - output */
28 #define FPGA_INIT_PDDIR          FPGA_PRG | FPGA_CLK | FPGA_DATA        /* just set outputs */
29
30
31 #define SET_FPGA(data)         immr->im_ioport.iop_pddat = (data)
32 #define GET_FPGA               immr->im_ioport.iop_pddat
33
34 #define FPGA_WRITE_1 {                                                    \
35         SET_FPGA(FPGA_PRG |            FPGA_DATA);  /* set clock to 0 */  \
36         SET_FPGA(FPGA_PRG |            FPGA_DATA);  /* set data to 1  */  \
37         SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);  /* set clock to 1 */  \
38         SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);}     /* set data to 1  */
39
40 #define FPGA_WRITE_0 {                                                    \
41         SET_FPGA(FPGA_PRG |            FPGA_DATA);  /* set clock to 0 */  \
42         SET_FPGA(FPGA_PRG);                         /* set data to 0  */  \
43         SET_FPGA(FPGA_PRG | FPGA_CLK);              /* set clock to 1 */  \
44         SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);}     /* set data to 1  */
45
46
47 int fpga_boot (unsigned char *fpgadata, int size)
48 {
49         volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
50         int i, index, len;
51         int count;
52
53 #ifdef CONFIG_SYS_FPGA_SPARTAN2
54         int j;
55         unsigned char data;
56 #else
57         unsigned char b;
58         int bit;
59 #endif
60
61         debug ("fpga_boot: fpgadata = %p, size = %d\n", fpgadata, size);
62
63         /* display infos on fpgaimage */
64         printf ("FPGA:");
65         index = 15;
66         for (i = 0; i < 4; i++) {
67                 len = fpgadata[index];
68                 printf (" %s", &(fpgadata[index + 1]));
69                 index += len + 3;
70         }
71         printf ("\n");
72
73
74         index = 0;
75
76 #ifdef CONFIG_SYS_FPGA_SPARTAN2
77         /* search for preamble 0xFFFFFFFF */
78         while (1) {
79                 if ((fpgadata[index] == 0xff) && (fpgadata[index + 1] == 0xff)
80                     && (fpgadata[index + 2] == 0xff)
81                     && (fpgadata[index + 3] == 0xff))
82                         break;  /* preamble found */
83                 else
84                         index++;
85         }
86 #else
87         /* search for preamble 0xFF2X */
88         for (index = 0; index < size - 1; index++) {
89                 if ((fpgadata[index] == 0xff)
90                     && ((fpgadata[index + 1] & 0xf0) == 0x30))
91                         break;
92         }
93         index += 2;
94 #endif
95
96         debug ("FPGA: configdata starts at position 0x%x\n", index);
97         debug ("FPGA: length of fpga-data %d\n", size - index);
98
99         /*
100          * Setup port pins for fpga programming
101          */
102         immr->im_ioport.iop_pddir = FPGA_INIT_PDDIR;
103
104         debug ("%s, ", ((GET_FPGA & FPGA_DONE) == 0) ? "NOT DONE" : "DONE");
105         debug ("%s\n", ((GET_FPGA & FPGA_INIT) == 0) ? "NOT INIT" : "INIT");
106
107         /*
108          * Init fpga by asserting and deasserting PROGRAM*
109          */
110         SET_FPGA (FPGA_CLK | FPGA_DATA);
111
112         /* Wait for FPGA init line low */
113         count = 0;
114         while (GET_FPGA & FPGA_INIT) {
115                 udelay (1000);  /* wait 1ms */
116                 /* Check for timeout - 100us max, so use 3ms */
117                 if (count++ > 3) {
118                         debug ("FPGA: Booting failed!\n");
119                         return ERROR_FPGA_PRG_INIT_LOW;
120                 }
121         }
122
123         debug ("%s, ", ((GET_FPGA & FPGA_DONE) == 0) ? "NOT DONE" : "DONE");
124         debug ("%s\n", ((GET_FPGA & FPGA_INIT) == 0) ? "NOT INIT" : "INIT");
125
126         /* deassert PROGRAM* */
127         SET_FPGA (FPGA_PRG | FPGA_CLK | FPGA_DATA);
128
129         /* Wait for FPGA end of init period .  */
130         count = 0;
131         while (!(GET_FPGA & FPGA_INIT)) {
132                 udelay (1000);  /* wait 1ms */
133                 /* Check for timeout */
134                 if (count++ > 3) {
135                         debug ("FPGA: Booting failed!\n");
136                         return ERROR_FPGA_PRG_INIT_HIGH;
137                 }
138         }
139
140         debug ("%s, ", ((GET_FPGA & FPGA_DONE) == 0) ? "NOT DONE" : "DONE");
141         debug ("%s\n", ((GET_FPGA & FPGA_INIT) == 0) ? "NOT INIT" : "INIT");
142
143         debug ("write configuration data into fpga\n");
144         /* write configuration-data into fpga... */
145
146 #ifdef CONFIG_SYS_FPGA_SPARTAN2
147         /*
148          * Load uncompressed image into fpga
149          */
150         for (i = index; i < size; i++) {
151 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
152                 if ((i % 1024) == 0)
153                         printf ("%6d out of %6d\r", i, size);   /* let them know we are alive */
154 #endif
155
156                 data = fpgadata[i];
157                 for (j = 0; j < 8; j++) {
158                         if ((data & 0x80) == 0x80) {
159                                 FPGA_WRITE_1;
160                         } else {
161                                 FPGA_WRITE_0;
162                         }
163                         data <<= 1;
164                 }
165         }
166         /* add some 0xff to the end of the file */
167         for (i = 0; i < 8; i++) {
168                 data = 0xff;
169                 for (j = 0; j < 8; j++) {
170                         if ((data & 0x80) == 0x80) {
171                                 FPGA_WRITE_1;
172                         } else {
173                                 FPGA_WRITE_0;
174                         }
175                         data <<= 1;
176                 }
177         }
178 #else
179         /* send 0xff 0x20 */
180         FPGA_WRITE_1;
181         FPGA_WRITE_1;
182         FPGA_WRITE_1;
183         FPGA_WRITE_1;
184         FPGA_WRITE_1;
185         FPGA_WRITE_1;
186         FPGA_WRITE_1;
187         FPGA_WRITE_1;
188         FPGA_WRITE_0;
189         FPGA_WRITE_0;
190         FPGA_WRITE_1;
191         FPGA_WRITE_0;
192         FPGA_WRITE_0;
193         FPGA_WRITE_0;
194         FPGA_WRITE_0;
195         FPGA_WRITE_0;
196
197         /*
198          ** Bit_DeCompression
199          **   Code 1           .. maxOnes     : n                 '1's followed by '0'
200          **        maxOnes + 1 .. maxOnes + 1 : n - 1             '1's no '0'
201          **        maxOnes + 2 .. 254         : n - (maxOnes + 2) '0's followed by '1'
202          **        255                        :                   '1'
203          */
204
205         for (i = index; i < size; i++) {
206                 b = fpgadata[i];
207                 if ((b >= 1) && (b <= MAX_ONES)) {
208                         for (bit = 0; bit < b; bit++) {
209                                 FPGA_WRITE_1;
210                         }
211                         FPGA_WRITE_0;
212                 } else if (b == (MAX_ONES + 1)) {
213                         for (bit = 1; bit < b; bit++) {
214                                 FPGA_WRITE_1;
215                         }
216                 } else if ((b >= (MAX_ONES + 2)) && (b <= 254)) {
217                         for (bit = 0; bit < (b - (MAX_ONES + 2)); bit++) {
218                                 FPGA_WRITE_0;
219                         }
220                         FPGA_WRITE_1;
221                 } else if (b == 255) {
222                         FPGA_WRITE_1;
223                 }
224         }
225 #endif
226         debug ("\n\n");
227         debug ("%s, ", ((GET_FPGA & FPGA_DONE) == 0) ? "NOT DONE" : "DONE");
228         debug ("%s\n", ((GET_FPGA & FPGA_INIT) == 0) ? "NOT INIT" : "INIT");
229
230         /*
231          * Check if fpga's DONE signal - correctly booted ?
232          */
233
234         /* Wait for FPGA end of programming period .  */
235         count = 0;
236         while (!(GET_FPGA & FPGA_DONE)) {
237                 udelay (1000);  /* wait 1ms */
238                 /* Check for timeout */
239                 if (count++ > 3) {
240                         debug ("FPGA: Booting failed!\n");
241                         return ERROR_FPGA_PRG_DONE;
242                 }
243         }
244
245         debug ("FPGA: Booting successful!\n");
246         return 0;
247 }