blob: 50d9e542d7a4dc454dfff75df2662abf7ab0537e [file] [log] [blame]
Stefano Babic3b8ac462010-06-29 11:47:48 +02001/*
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
36static lattice_board_specific_func *pfns;
Wolfgang Denkfb2d6ef2011-08-05 02:26:31 +000037static const char *fpga_image;
Stefano Babic3b8ac462010-06-29 11:47:48 +020038static unsigned long read_bytes;
39static unsigned long bufsize;
40static unsigned short expectedCRC;
41
42/*
43 * External variables and functions declared in ivm_core.c module.
44 */
45extern unsigned short g_usCalculatedCRC;
46extern unsigned short g_usDataType;
47extern unsigned char *g_pucIntelBuffer;
48extern unsigned char *g_pucHeapMemory;
49extern unsigned short g_iHeapCounter;
50extern unsigned short g_iHEAPSize;
51extern unsigned short g_usIntelDataIndex;
52extern unsigned short g_usIntelBufferSize;
53extern 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 */
78void ispVMDelay(unsigned short delay)
79{
80 if (delay & 0x8000)
81 delay = (delay & ~0x8000) * 1000;
82 udelay(delay);
83}
84
85void 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
104unsigned char readPort(void)
105{
106 return pfns->jtag_get_tdo();
107}
108
109void sclock(void)
110{
111 writePort(g_ucPinTCK, 0x01);
112 writePort(g_ucPinTCK, 0x00);
113}
114
115void 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 */
142unsigned 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
195signed 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
276static 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
Wolfgang Denkfb2d6ef2011-08-05 02:26:31 +0000305int lattice_load(Lattice_desc *desc, const void *buf, size_t bsize)
Stefano Babic3b8ac462010-06-29 11:47:48 +0200306{
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 0x%x size 0x%x...\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
Wolfgang Denkfb2d6ef2011-08-05 02:26:31 +0000338int lattice_dump(Lattice_desc *desc, const void *buf, size_t bsize)
Stefano Babic3b8ac462010-06-29 11:47:48 +0200339{
340 puts("Dump not supported for Lattice FPGA\n");
341
342 return FPGA_FAIL;
343
344}
345
346int 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}