arm: mach-k3: Enable dcache in SPL
[oweals/u-boot.git] / drivers / fpga / lattice.c
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  */
60 void ispVMDelay(unsigned short delay)
61 {
62         if (delay & 0x8000)
63                 delay = (delay & ~0x8000) * 1000;
64         udelay(delay);
65 }
66
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
86 unsigned char readPort(void)
87 {
88         return pfns->jtag_get_tdo();
89 }
90
91 void sclock(void)
92 {
93         writePort(g_ucPinTCK, 0x01);
94         writePort(g_ucPinTCK, 0x00);
95 }
96
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  */
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
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
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
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
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
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 }