blob: 3f481e385655354a8f268ecfde087473f32623c7 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Stefano Babicec65c592010-06-29 11:47:48 +02002/*
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.
Stefano Babicec65c592010-06-29 11:47:48 +020011 */
12
Simon Glass0f2af882020-05-10 11:40:05 -060013#include <log.h>
Stefano Babicec65c592010-06-29 11:47:48 +020014#include <malloc.h>
15#include <fpga.h>
16#include <lattice.h>
Simon Glassdbd79542020-05-10 11:40:11 -060017#include <linux/delay.h>
Stefano Babicec65c592010-06-29 11:47:48 +020018
19static lattice_board_specific_func *pfns;
Wolfgang Denkb2c66a82011-08-05 02:26:31 +000020static const char *fpga_image;
Stefano Babicec65c592010-06-29 11:47:48 +020021static unsigned long read_bytes;
22static unsigned long bufsize;
23static unsigned short expectedCRC;
24
25/*
26 * External variables and functions declared in ivm_core.c module.
27 */
28extern unsigned short g_usCalculatedCRC;
29extern unsigned short g_usDataType;
30extern unsigned char *g_pucIntelBuffer;
31extern unsigned char *g_pucHeapMemory;
32extern unsigned short g_iHeapCounter;
33extern unsigned short g_iHEAPSize;
34extern unsigned short g_usIntelDataIndex;
35extern unsigned short g_usIntelBufferSize;
36extern char *const g_szSupportedVersions[];
37
Stefano Babicec65c592010-06-29 11:47:48 +020038/*
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 */
60void ispVMDelay(unsigned short delay)
61{
62 if (delay & 0x8000)
63 delay = (delay & ~0x8000) * 1000;
64 udelay(delay);
65}
66
67void 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
86unsigned char readPort(void)
87{
88 return pfns->jtag_get_tdo();
89}
90
91void sclock(void)
92{
93 writePort(g_ucPinTCK, 0x01);
94 writePort(g_ucPinTCK, 0x00);
95}
96
97void 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 */
124unsigned 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
177signed 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
258static int lattice_validate(Lattice_desc *desc, const char *fn)
259{
York Sun4a598092013-04-01 11:29:11 -0700260 int ret_val = false;
Stefano Babicec65c592010-06-29 11:47:48 +0200261
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) {
York Sun4a598092013-04-01 11:29:11 -0700268 ret_val = true;
Stefano Babicec65c592010-06-29 11:47:48 +0200269 } 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
Wolfgang Denkb2c66a82011-08-05 02:26:31 +0000287int lattice_load(Lattice_desc *desc, const void *buf, size_t bsize)
Stefano Babicec65c592010-06-29 11:47:48 +0200288{
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:"
Marek Vasut445e3ac2011-10-24 23:40:00 +0000302 " addr %p size 0x%lx...\n",
Stefano Babicec65c592010-06-29 11:47:48 +0200303 __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
Wolfgang Denkb2c66a82011-08-05 02:26:31 +0000320int lattice_dump(Lattice_desc *desc, const void *buf, size_t bsize)
Stefano Babicec65c592010-06-29 11:47:48 +0200321{
322 puts("Dump not supported for Lattice FPGA\n");
323
324 return FPGA_FAIL;
325
326}
327
328int 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}