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