xref: /openbmc/u-boot/drivers/fpga/lattice.c (revision 419adbfb)
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 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 
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 }
398