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