]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/fpga/lattice.c
Merge branch 'u-boot-imx/master' into 'u-boot-arm/master'
[karo-tx-uboot.git] / drivers / fpga / lattice.c
1 /*
2  * (C) Copyright 2010
3  * Stefano Babic, DENX Software Engineering, sbabic@denx.de.
4  *
5  * (C) Copyright 2002
6  * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
7  *
8  * ispVM functions adapted from Lattice's ispmVMEmbedded code:
9  * Copyright 2009 Lattice Semiconductor Corp.
10  *
11  * See file CREDITS for list of people who contributed to this
12  * project.
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License as
16  * published by the Free Software Foundation; either version 2 of
17  * the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27  * MA 02111-1307 USA
28  *
29  */
30
31 #include <common.h>
32 #include <malloc.h>
33 #include <fpga.h>
34 #include <lattice.h>
35
36 static lattice_board_specific_func *pfns;
37 static const char *fpga_image;
38 static unsigned long read_bytes;
39 static unsigned long bufsize;
40 static unsigned short expectedCRC;
41
42 /*
43  * External variables and functions declared in ivm_core.c module.
44  */
45 extern unsigned short g_usCalculatedCRC;
46 extern unsigned short g_usDataType;
47 extern unsigned char *g_pucIntelBuffer;
48 extern unsigned char *g_pucHeapMemory;
49 extern unsigned short g_iHeapCounter;
50 extern unsigned short g_iHEAPSize;
51 extern unsigned short g_usIntelDataIndex;
52 extern unsigned short g_usIntelBufferSize;
53 extern char *const g_szSupportedVersions[];
54
55
56 /*
57  * ispVMDelay
58  *
59  * Users must implement a delay to observe a_usTimeDelay, where
60  * bit 15 of the a_usTimeDelay defines the unit.
61  *      1 = milliseconds
62  *      0 = microseconds
63  * Example:
64  *      a_usTimeDelay = 0x0001 = 1 microsecond delay.
65  *      a_usTimeDelay = 0x8001 = 1 millisecond delay.
66  *
67  * This subroutine is called upon to provide a delay from 1 millisecond to a few
68  * hundreds milliseconds each time.
69  * It is understood that due to a_usTimeDelay is defined as unsigned short, a 16
70  * bits integer, this function is restricted to produce a delay to 64000
71  * micro-seconds or 32000 milli-second maximum. The VME file will never pass on
72  * to this function a delay time > those maximum number. If it needs more than
73  * those maximum, the VME file will launch the delay function several times to
74  * realize a larger delay time cummulatively.
75  * It is perfectly alright to provide a longer delay than required. It is not
76  * acceptable if the delay is shorter.
77  */
78 void ispVMDelay(unsigned short delay)
79 {
80         if (delay & 0x8000)
81                 delay = (delay & ~0x8000) * 1000;
82         udelay(delay);
83 }
84
85 void writePort(unsigned char a_ucPins, unsigned char a_ucValue)
86 {
87         a_ucValue = a_ucValue ? 1 : 0;
88
89         switch (a_ucPins) {
90         case g_ucPinTDI:
91                 pfns->jtag_set_tdi(a_ucValue);
92                 break;
93         case g_ucPinTCK:
94                 pfns->jtag_set_tck(a_ucValue);
95                 break;
96         case g_ucPinTMS:
97                 pfns->jtag_set_tms(a_ucValue);
98                 break;
99         default:
100                 printf("%s: requested unknown pin\n", __func__);
101         }
102 }
103
104 unsigned char readPort(void)
105 {
106         return pfns->jtag_get_tdo();
107 }
108
109 void sclock(void)
110 {
111         writePort(g_ucPinTCK, 0x01);
112         writePort(g_ucPinTCK, 0x00);
113 }
114
115 void calibration(void)
116 {
117         /* Apply 2 pulses to TCK. */
118         writePort(g_ucPinTCK, 0x00);
119         writePort(g_ucPinTCK, 0x01);
120         writePort(g_ucPinTCK, 0x00);
121         writePort(g_ucPinTCK, 0x01);
122         writePort(g_ucPinTCK, 0x00);
123
124         ispVMDelay(0x8001);
125
126         /* Apply 2 pulses to TCK. */
127         writePort(g_ucPinTCK, 0x01);
128         writePort(g_ucPinTCK, 0x00);
129         writePort(g_ucPinTCK, 0x01);
130         writePort(g_ucPinTCK, 0x00);
131 }
132
133 /*
134  * GetByte
135  *
136  * Returns a byte to the caller. The returned byte depends on the
137  * g_usDataType register. If the HEAP_IN bit is set, then the byte
138  * is returned from the HEAP. If the LHEAP_IN bit is set, then
139  * the byte is returned from the intelligent buffer. Otherwise,
140  * the byte is returned directly from the VME file.
141  */
142 unsigned char GetByte(void)
143 {
144         unsigned char ucData;
145         unsigned int block_size = 4 * 1024;
146
147         if (g_usDataType & HEAP_IN) {
148
149                 /*
150                  * Get data from repeat buffer.
151                  */
152
153                 if (g_iHeapCounter > g_iHEAPSize) {
154
155                         /*
156                          * Data over-run.
157                          */
158
159                         return 0xFF;
160                 }
161
162                 ucData = g_pucHeapMemory[g_iHeapCounter++];
163         } else if (g_usDataType & LHEAP_IN) {
164
165                 /*
166                  * Get data from intel buffer.
167                  */
168
169                 if (g_usIntelDataIndex >= g_usIntelBufferSize) {
170                         return 0xFF;
171                 }
172
173                 ucData = g_pucIntelBuffer[g_usIntelDataIndex++];
174         } else {
175                 if (read_bytes == bufsize) {
176                         return 0xFF;
177                 }
178                 ucData = *fpga_image++;
179                 read_bytes++;
180
181                 if (!(read_bytes % block_size)) {
182                         printf("Downloading FPGA %ld/%ld completed\r",
183                                 read_bytes,
184                                 bufsize);
185                 }
186
187                 if (expectedCRC != 0) {
188                         ispVMCalculateCRC32(ucData);
189                 }
190         }
191
192         return ucData;
193 }
194
195 signed char ispVM(void)
196 {
197         char szFileVersion[9]      = { 0 };
198         signed char cRetCode         = 0;
199         signed char cIndex           = 0;
200         signed char cVersionIndex    = 0;
201         unsigned char ucReadByte     = 0;
202         unsigned short crc;
203
204         g_pucHeapMemory         = NULL;
205         g_iHeapCounter          = 0;
206         g_iHEAPSize             = 0;
207         g_usIntelDataIndex      = 0;
208         g_usIntelBufferSize     = 0;
209         g_usCalculatedCRC = 0;
210         expectedCRC   = 0;
211         ucReadByte = GetByte();
212         switch (ucReadByte) {
213         case FILE_CRC:
214                 crc = (unsigned char)GetByte();
215                 crc <<= 8;
216                 crc |= GetByte();
217                 expectedCRC = crc;
218
219                 for (cIndex = 0; cIndex < 8; cIndex++)
220                         szFileVersion[cIndex] = GetByte();
221
222                 break;
223         default:
224                 szFileVersion[0] = (signed char) ucReadByte;
225                 for (cIndex = 1; cIndex < 8; cIndex++)
226                         szFileVersion[cIndex] = GetByte();
227
228                 break;
229         }
230
231         /*
232          *
233          * Compare the VME file version against the supported version.
234          *
235          */
236
237         for (cVersionIndex = 0; g_szSupportedVersions[cVersionIndex] != 0;
238                 cVersionIndex++) {
239                 for (cIndex = 0; cIndex < 8; cIndex++) {
240                         if (szFileVersion[cIndex] !=
241                                 g_szSupportedVersions[cVersionIndex][cIndex]) {
242                                 cRetCode = VME_VERSION_FAILURE;
243                                 break;
244                         }
245                         cRetCode = 0;
246                 }
247
248                 if (cRetCode == 0) {
249                         break;
250                 }
251         }
252
253         if (cRetCode < 0) {
254                 return VME_VERSION_FAILURE;
255         }
256
257         printf("VME file checked: starting downloading to FPGA\n");
258
259         ispVMStart();
260
261         cRetCode = ispVMCode();
262
263         ispVMEnd();
264         ispVMFreeMem();
265         puts("\n");
266
267         if (cRetCode == 0 && expectedCRC != 0 &&
268                         (expectedCRC != g_usCalculatedCRC)) {
269                 printf("Expected CRC:   0x%.4X\n", expectedCRC);
270                 printf("Calculated CRC: 0x%.4X\n", g_usCalculatedCRC);
271                 return VME_CRC_FAILURE;
272         }
273         return cRetCode;
274 }
275
276 static int lattice_validate(Lattice_desc *desc, const char *fn)
277 {
278         int ret_val = false;
279
280         if (desc) {
281                 if ((desc->family > min_lattice_type) &&
282                         (desc->family < max_lattice_type)) {
283                         if ((desc->iface > min_lattice_iface_type) &&
284                                 (desc->iface < max_lattice_iface_type)) {
285                                 if (desc->size) {
286                                         ret_val = true;
287                                 } else {
288                                         printf("%s: NULL part size\n", fn);
289                                 }
290                         } else {
291                                 printf("%s: Invalid Interface type, %d\n",
292                                         fn, desc->iface);
293                         }
294                 } else {
295                         printf("%s: Invalid family type, %d\n",
296                                 fn, desc->family);
297                 }
298         } else {
299                 printf("%s: NULL descriptor!\n", fn);
300         }
301
302         return ret_val;
303 }
304
305 int lattice_load(Lattice_desc *desc, const void *buf, size_t bsize)
306 {
307         int ret_val = FPGA_FAIL;
308
309         if (!lattice_validate(desc, (char *)__func__)) {
310                 printf("%s: Invalid device descriptor\n", __func__);
311         } else {
312                 pfns = desc->iface_fns;
313
314                 switch (desc->family) {
315                 case Lattice_XP2:
316                         fpga_image = buf;
317                         read_bytes = 0;
318                         bufsize = bsize;
319                         debug("%s: Launching the Lattice ISPVME Loader:"
320                                 " addr %p size 0x%lx...\n",
321                                 __func__, fpga_image, bufsize);
322                         ret_val = ispVM();
323                         if (ret_val)
324                                 printf("%s: error %d downloading FPGA image\n",
325                                         __func__, ret_val);
326                         else
327                                 puts("FPGA downloaded successfully\n");
328                         break;
329                 default:
330                         printf("%s: Unsupported family type, %d\n",
331                                         __func__, desc->family);
332                 }
333         }
334
335         return ret_val;
336 }
337
338 int lattice_dump(Lattice_desc *desc, const void *buf, size_t bsize)
339 {
340         puts("Dump not supported for Lattice FPGA\n");
341
342         return FPGA_FAIL;
343
344 }
345
346 int lattice_info(Lattice_desc *desc)
347 {
348         int ret_val = FPGA_FAIL;
349
350         if (lattice_validate(desc, (char *)__func__)) {
351                 printf("Family:        \t");
352                 switch (desc->family) {
353                 case Lattice_XP2:
354                         puts("XP2\n");
355                         break;
356                         /* Add new family types here */
357                 default:
358                         printf("Unknown family type, %d\n", desc->family);
359                 }
360
361                 puts("Interface type:\t");
362                 switch (desc->iface) {
363                 case lattice_jtag_mode:
364                         puts("JTAG Mode\n");
365                         break;
366                         /* Add new interface types here */
367                 default:
368                         printf("Unsupported interface type, %d\n", desc->iface);
369                 }
370
371                 printf("Device Size:   \t%d bytes\n",
372                                 desc->size);
373
374                 if (desc->iface_fns) {
375                         printf("Device Function Table @ 0x%p\n",
376                                 desc->iface_fns);
377                         switch (desc->family) {
378                         case Lattice_XP2:
379                                 break;
380                                 /* Add new family types here */
381                         default:
382                                 break;
383                         }
384                 } else {
385                         puts("No Device Function Table.\n");
386                 }
387
388                 if (desc->desc)
389                         printf("Model:         \t%s\n", desc->desc);
390
391                 ret_val = FPGA_SUCCESS;
392         } else {
393                 printf("%s: Invalid device descriptor\n", __func__);
394         }
395
396         return ret_val;
397 }