blob: 2ff716c25228f513fe09fdbc5346caeeed3ff8d2 [file] [log] [blame]
Michal Simekd5dae852013-04-22 15:43:02 +02001/*
2 * (C) Copyright 2012-2013, Xilinx, Michal Simek
3 *
4 * (C) Copyright 2012
5 * Joe Hershberger <joe.hershberger@ni.com>
6 *
Wolfgang Denk3765b3e2013-10-07 13:07:26 +02007 * SPDX-License-Identifier: GPL-2.0+
Michal Simekd5dae852013-04-22 15:43:02 +02008 */
9
10#include <common.h>
Simon Glass24b852a2015-11-08 23:47:45 -070011#include <console.h>
Michal Simekd5dae852013-04-22 15:43:02 +020012#include <asm/io.h>
Siva Durga Prasad Paladugu1a897662014-03-14 16:35:37 +053013#include <fs.h>
Michal Simekd5dae852013-04-22 15:43:02 +020014#include <zynqpl.h>
Alexey Brodkin1ace4022014-02-26 17:47:58 +040015#include <linux/sizes.h>
Michal Simekd5dae852013-04-22 15:43:02 +020016#include <asm/arch/hardware.h>
17#include <asm/arch/sys_proto.h>
18
19#define DEVCFG_CTRL_PCFG_PROG_B 0x40000000
20#define DEVCFG_ISR_FATAL_ERROR_MASK 0x00740040
21#define DEVCFG_ISR_ERROR_FLAGS_MASK 0x00340840
22#define DEVCFG_ISR_RX_FIFO_OV 0x00040000
23#define DEVCFG_ISR_DMA_DONE 0x00002000
24#define DEVCFG_ISR_PCFG_DONE 0x00000004
25#define DEVCFG_STATUS_DMA_CMD_Q_F 0x80000000
26#define DEVCFG_STATUS_DMA_CMD_Q_E 0x40000000
27#define DEVCFG_STATUS_DMA_DONE_CNT_MASK 0x30000000
28#define DEVCFG_STATUS_PCFG_INIT 0x00000010
Soren Brinkmann5f932272013-06-14 17:43:24 -070029#define DEVCFG_MCTRL_PCAP_LPBK 0x00000010
Michal Simekd5dae852013-04-22 15:43:02 +020030#define DEVCFG_MCTRL_RFIFO_FLUSH 0x00000002
31#define DEVCFG_MCTRL_WFIFO_FLUSH 0x00000001
32
33#ifndef CONFIG_SYS_FPGA_WAIT
34#define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100 /* 10 ms */
35#endif
36
37#ifndef CONFIG_SYS_FPGA_PROG_TIME
Michal Simekfd2b10b2013-06-17 13:54:07 +020038#define CONFIG_SYS_FPGA_PROG_TIME (CONFIG_SYS_HZ * 4) /* 4 s */
Michal Simekd5dae852013-04-22 15:43:02 +020039#endif
40
Michal Simekd5dae852013-04-22 15:43:02 +020041#define DUMMY_WORD 0xffffffff
42
43/* Xilinx binary format header */
44static const u32 bin_format[] = {
45 DUMMY_WORD, /* Dummy words */
46 DUMMY_WORD,
47 DUMMY_WORD,
48 DUMMY_WORD,
49 DUMMY_WORD,
50 DUMMY_WORD,
51 DUMMY_WORD,
52 DUMMY_WORD,
53 0x000000bb, /* Sync word */
54 0x11220044, /* Sync word */
55 DUMMY_WORD,
56 DUMMY_WORD,
57 0xaa995566, /* Sync word */
58};
59
60#define SWAP_NO 1
61#define SWAP_DONE 2
62
63/*
64 * Load the whole word from unaligned buffer
65 * Keep in your mind that it is byte loading on little-endian system
66 */
67static u32 load_word(const void *buf, u32 swap)
68{
69 u32 word = 0;
70 u8 *bitc = (u8 *)buf;
71 int p;
72
73 if (swap == SWAP_NO) {
74 for (p = 0; p < 4; p++) {
75 word <<= 8;
76 word |= bitc[p];
77 }
78 } else {
79 for (p = 3; p >= 0; p--) {
80 word <<= 8;
81 word |= bitc[p];
82 }
83 }
84
85 return word;
86}
87
88static u32 check_header(const void *buf)
89{
90 u32 i, pattern;
91 int swap = SWAP_NO;
92 u32 *test = (u32 *)buf;
93
94 debug("%s: Let's check bitstream header\n", __func__);
95
96 /* Checking that passing bin is not a bitstream */
97 for (i = 0; i < ARRAY_SIZE(bin_format); i++) {
98 pattern = load_word(&test[i], swap);
99
100 /*
101 * Bitstreams in binary format are swapped
102 * compare to regular bistream.
103 * Do not swap dummy word but if swap is done assume
104 * that parsing buffer is binary format
105 */
106 if ((__swab32(pattern) != DUMMY_WORD) &&
107 (__swab32(pattern) == bin_format[i])) {
108 pattern = __swab32(pattern);
109 swap = SWAP_DONE;
110 debug("%s: data swapped - let's swap\n", __func__);
111 }
112
113 debug("%s: %d/%x: pattern %x/%x bin_format\n", __func__, i,
114 (u32)&test[i], pattern, bin_format[i]);
115 if (pattern != bin_format[i]) {
116 debug("%s: Bitstream is not recognized\n", __func__);
117 return 0;
118 }
119 }
120 debug("%s: Found bitstream header at %x %s swapinng\n", __func__,
121 (u32)buf, swap == SWAP_NO ? "without" : "with");
122
123 return swap;
124}
125
126static void *check_data(u8 *buf, size_t bsize, u32 *swap)
127{
128 u32 word, p = 0; /* possition */
129
130 /* Because buf doesn't need to be aligned let's read it by chars */
131 for (p = 0; p < bsize; p++) {
132 word = load_word(&buf[p], SWAP_NO);
133 debug("%s: word %x %x/%x\n", __func__, word, p, (u32)&buf[p]);
134
135 /* Find the first bitstream dummy word */
136 if (word == DUMMY_WORD) {
137 debug("%s: Found dummy word at position %x/%x\n",
138 __func__, p, (u32)&buf[p]);
139 *swap = check_header(&buf[p]);
140 if (*swap) {
141 /* FIXME add full bitstream checking here */
142 return &buf[p];
143 }
144 }
145 /* Loop can be huge - support CTRL + C */
146 if (ctrlc())
Michal Simek42a74a02014-04-25 13:51:58 +0200147 return NULL;
Michal Simekd5dae852013-04-22 15:43:02 +0200148 }
Michal Simek42a74a02014-04-25 13:51:58 +0200149 return NULL;
Michal Simekd5dae852013-04-22 15:43:02 +0200150}
151
Siva Durga Prasad Paladugua0735a32014-03-12 17:09:26 +0530152static int zynq_dma_transfer(u32 srcbuf, u32 srclen, u32 dstbuf, u32 dstlen)
Michal Simekd5dae852013-04-22 15:43:02 +0200153{
Siva Durga Prasad Paladugua0735a32014-03-12 17:09:26 +0530154 unsigned long ts;
155 u32 isr_status;
Michal Simekd5dae852013-04-22 15:43:02 +0200156
Siva Durga Prasad Paladugua0735a32014-03-12 17:09:26 +0530157 /* Set up the transfer */
158 writel((u32)srcbuf, &devcfg_base->dma_src_addr);
159 writel(dstbuf, &devcfg_base->dma_dst_addr);
160 writel(srclen, &devcfg_base->dma_src_len);
161 writel(dstlen, &devcfg_base->dma_dst_len);
Michal Simekd5dae852013-04-22 15:43:02 +0200162
Siva Durga Prasad Paladugua0735a32014-03-12 17:09:26 +0530163 isr_status = readl(&devcfg_base->int_sts);
Michal Simekd5dae852013-04-22 15:43:02 +0200164
Siva Durga Prasad Paladugua0735a32014-03-12 17:09:26 +0530165 /* Polling the PCAP_INIT status for Set */
166 ts = get_timer(0);
167 while (!(isr_status & DEVCFG_ISR_DMA_DONE)) {
168 if (isr_status & DEVCFG_ISR_ERROR_FLAGS_MASK) {
169 debug("%s: Error: isr = 0x%08X\n", __func__,
170 isr_status);
171 debug("%s: Write count = 0x%08X\n", __func__,
172 readl(&devcfg_base->write_count));
173 debug("%s: Read count = 0x%08X\n", __func__,
174 readl(&devcfg_base->read_count));
Michal Simekd5dae852013-04-22 15:43:02 +0200175
Siva Durga Prasad Paladugua0735a32014-03-12 17:09:26 +0530176 return FPGA_FAIL;
Novasys Ingenieriec83a35f2013-11-27 09:03:01 +0100177 }
Siva Durga Prasad Paladugua0735a32014-03-12 17:09:26 +0530178 if (get_timer(ts) > CONFIG_SYS_FPGA_PROG_TIME) {
179 printf("%s: Timeout wait for DMA to complete\n",
180 __func__);
181 return FPGA_FAIL;
182 }
183 isr_status = readl(&devcfg_base->int_sts);
Michal Simekd5dae852013-04-22 15:43:02 +0200184 }
185
Siva Durga Prasad Paladugua0735a32014-03-12 17:09:26 +0530186 debug("%s: DMA transfer is done\n", __func__);
187
188 /* Clear out the DMA status */
189 writel(DEVCFG_ISR_DMA_DONE, &devcfg_base->int_sts);
190
191 return FPGA_SUCCESS;
192}
193
Michal Simek5b815c92014-05-02 14:15:27 +0200194static int zynq_dma_xfer_init(bitstream_type bstype)
Siva Durga Prasad Paladugua0735a32014-03-12 17:09:26 +0530195{
196 u32 status, control, isr_status;
197 unsigned long ts;
198
Soren Brinkmann5f932272013-06-14 17:43:24 -0700199 /* Clear loopback bit */
200 clrbits_le32(&devcfg_base->mctrl, DEVCFG_MCTRL_PCAP_LPBK);
201
Michal Simek5b815c92014-05-02 14:15:27 +0200202 if (bstype != BIT_PARTIAL) {
Michal Simekd5dae852013-04-22 15:43:02 +0200203 zynq_slcr_devcfg_disable();
204
205 /* Setting PCFG_PROG_B signal to high */
206 control = readl(&devcfg_base->ctrl);
207 writel(control | DEVCFG_CTRL_PCFG_PROG_B, &devcfg_base->ctrl);
208 /* Setting PCFG_PROG_B signal to low */
209 writel(control & ~DEVCFG_CTRL_PCFG_PROG_B, &devcfg_base->ctrl);
210
211 /* Polling the PCAP_INIT status for Reset */
212 ts = get_timer(0);
213 while (readl(&devcfg_base->status) & DEVCFG_STATUS_PCFG_INIT) {
214 if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) {
215 printf("%s: Timeout wait for INIT to clear\n",
216 __func__);
217 return FPGA_FAIL;
218 }
219 }
220
221 /* Setting PCFG_PROG_B signal to high */
222 writel(control | DEVCFG_CTRL_PCFG_PROG_B, &devcfg_base->ctrl);
223
224 /* Polling the PCAP_INIT status for Set */
225 ts = get_timer(0);
226 while (!(readl(&devcfg_base->status) &
227 DEVCFG_STATUS_PCFG_INIT)) {
228 if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) {
229 printf("%s: Timeout wait for INIT to set\n",
230 __func__);
231 return FPGA_FAIL;
232 }
233 }
234 }
235
236 isr_status = readl(&devcfg_base->int_sts);
237
238 /* Clear it all, so if Boot ROM comes back, it can proceed */
239 writel(0xFFFFFFFF, &devcfg_base->int_sts);
240
241 if (isr_status & DEVCFG_ISR_FATAL_ERROR_MASK) {
242 debug("%s: Fatal errors in PCAP 0x%X\n", __func__, isr_status);
243
244 /* If RX FIFO overflow, need to flush RX FIFO first */
245 if (isr_status & DEVCFG_ISR_RX_FIFO_OV) {
246 writel(DEVCFG_MCTRL_RFIFO_FLUSH, &devcfg_base->mctrl);
247 writel(0xFFFFFFFF, &devcfg_base->int_sts);
248 }
249 return FPGA_FAIL;
250 }
251
252 status = readl(&devcfg_base->status);
253
254 debug("%s: Status = 0x%08X\n", __func__, status);
255
256 if (status & DEVCFG_STATUS_DMA_CMD_Q_F) {
257 debug("%s: Error: device busy\n", __func__);
258 return FPGA_FAIL;
259 }
260
261 debug("%s: Device ready\n", __func__);
262
263 if (!(status & DEVCFG_STATUS_DMA_CMD_Q_E)) {
264 if (!(readl(&devcfg_base->int_sts) & DEVCFG_ISR_DMA_DONE)) {
265 /* Error state, transfer cannot occur */
266 debug("%s: ISR indicates error\n", __func__);
267 return FPGA_FAIL;
268 } else {
269 /* Clear out the status */
270 writel(DEVCFG_ISR_DMA_DONE, &devcfg_base->int_sts);
271 }
272 }
273
274 if (status & DEVCFG_STATUS_DMA_DONE_CNT_MASK) {
275 /* Clear the count of completed DMA transfers */
276 writel(DEVCFG_STATUS_DMA_DONE_CNT_MASK, &devcfg_base->status);
277 }
278
Siva Durga Prasad Paladugua0735a32014-03-12 17:09:26 +0530279 return FPGA_SUCCESS;
280}
281
282static u32 *zynq_align_dma_buffer(u32 *buf, u32 len, u32 swap)
283{
284 u32 *new_buf;
285 u32 i;
286
287 if ((u32)buf != ALIGN((u32)buf, ARCH_DMA_MINALIGN)) {
288 new_buf = (u32 *)ALIGN((u32)buf, ARCH_DMA_MINALIGN);
289
290 /*
291 * This might be dangerous but permits to flash if
292 * ARCH_DMA_MINALIGN is greater than header size
293 */
294 if (new_buf > buf) {
295 debug("%s: Aligned buffer is after buffer start\n",
296 __func__);
297 new_buf -= ARCH_DMA_MINALIGN;
298 }
299 printf("%s: Align buffer at %x to %x(swap %d)\n", __func__,
300 (u32)buf, (u32)new_buf, swap);
301
302 for (i = 0; i < (len/4); i++)
303 new_buf[i] = load_word(&buf[i], swap);
304
305 buf = new_buf;
306 } else if (swap != SWAP_DONE) {
307 /* For bitstream which are aligned */
308 u32 *new_buf = (u32 *)buf;
309
310 printf("%s: Bitstream is not swapped(%d) - swap it\n", __func__,
311 swap);
312
313 for (i = 0; i < (len/4); i++)
314 new_buf[i] = load_word(&buf[i], swap);
315 }
316
317 return buf;
318}
319
Siva Durga Prasad Paladugu31081852014-03-13 11:57:34 +0530320static int zynq_validate_bitstream(xilinx_desc *desc, const void *buf,
321 size_t bsize, u32 blocksize, u32 *swap,
Michal Simek5b815c92014-05-02 14:15:27 +0200322 bitstream_type *bstype)
Siva Durga Prasad Paladugua0735a32014-03-12 17:09:26 +0530323{
Siva Durga Prasad Paladugua0735a32014-03-12 17:09:26 +0530324 u32 *buf_start;
Siva Durga Prasad Paladugu31081852014-03-13 11:57:34 +0530325 u32 diff;
Siva Durga Prasad Paladugua0735a32014-03-12 17:09:26 +0530326
Siva Durga Prasad Paladugu31081852014-03-13 11:57:34 +0530327 buf_start = check_data((u8 *)buf, blocksize, swap);
Siva Durga Prasad Paladugua0735a32014-03-12 17:09:26 +0530328
Siva Durga Prasad Paladugua0735a32014-03-12 17:09:26 +0530329 if (!buf_start)
330 return FPGA_FAIL;
331
332 /* Check if data is postpone from start */
333 diff = (u32)buf_start - (u32)buf;
334 if (diff) {
335 printf("%s: Bitstream is not validated yet (diff %x)\n",
336 __func__, diff);
337 return FPGA_FAIL;
338 }
339
340 if ((u32)buf < SZ_1M) {
341 printf("%s: Bitstream has to be placed up to 1MB (%x)\n",
342 __func__, (u32)buf);
343 return FPGA_FAIL;
344 }
345
Michal Simek5b815c92014-05-02 14:15:27 +0200346 if (zynq_dma_xfer_init(*bstype))
Siva Durga Prasad Paladugu31081852014-03-13 11:57:34 +0530347 return FPGA_FAIL;
348
349 return 0;
350}
351
Michal Simek7a78bd22014-05-02 14:09:30 +0200352static int zynq_load(xilinx_desc *desc, const void *buf, size_t bsize,
353 bitstream_type bstype)
Siva Durga Prasad Paladugu31081852014-03-13 11:57:34 +0530354{
355 unsigned long ts; /* Timestamp */
Siva Durga Prasad Paladugu31081852014-03-13 11:57:34 +0530356 u32 isr_status, swap;
357
358 /*
359 * send bsize inplace of blocksize as it was not a bitstream
360 * in chunks
361 */
362 if (zynq_validate_bitstream(desc, buf, bsize, bsize, &swap,
Michal Simek5b815c92014-05-02 14:15:27 +0200363 &bstype))
Siva Durga Prasad Paladugua0735a32014-03-12 17:09:26 +0530364 return FPGA_FAIL;
365
366 buf = zynq_align_dma_buffer((u32 *)buf, bsize, swap);
367
Michal Simekd5dae852013-04-22 15:43:02 +0200368 debug("%s: Source = 0x%08X\n", __func__, (u32)buf);
369 debug("%s: Size = %zu\n", __func__, bsize);
370
Jagannadha Sutradharudu Tekiec4b73f2013-09-20 18:39:47 +0530371 /* flush(clean & invalidate) d-cache range buf */
372 flush_dcache_range((u32)buf, (u32)buf +
373 roundup(bsize, ARCH_DMA_MINALIGN));
374
Siva Durga Prasad Paladugua0735a32014-03-12 17:09:26 +0530375 if (zynq_dma_transfer((u32)buf | 1, bsize >> 2, 0xffffffff, 0))
376 return FPGA_FAIL;
Michal Simekd5dae852013-04-22 15:43:02 +0200377
378 isr_status = readl(&devcfg_base->int_sts);
Michal Simekd5dae852013-04-22 15:43:02 +0200379 /* Check FPGA configuration completion */
380 ts = get_timer(0);
381 while (!(isr_status & DEVCFG_ISR_PCFG_DONE)) {
382 if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) {
383 printf("%s: Timeout wait for FPGA to config\n",
384 __func__);
385 return FPGA_FAIL;
386 }
387 isr_status = readl(&devcfg_base->int_sts);
388 }
389
390 debug("%s: FPGA config done\n", __func__);
391
Michal Simek5b815c92014-05-02 14:15:27 +0200392 if (bstype != BIT_PARTIAL)
Michal Simekd5dae852013-04-22 15:43:02 +0200393 zynq_slcr_devcfg_enable();
394
395 return FPGA_SUCCESS;
396}
397
Siva Durga Prasad Paladugu1a897662014-03-14 16:35:37 +0530398#if defined(CONFIG_CMD_FPGA_LOADFS)
399static int zynq_loadfs(xilinx_desc *desc, const void *buf, size_t bsize,
400 fpga_fs_info *fsinfo)
401{
402 unsigned long ts; /* Timestamp */
403 u32 isr_status, swap;
404 u32 partialbit = 0;
Suriyan Ramasamid455d872014-11-17 14:39:38 -0800405 loff_t blocksize, actread;
406 loff_t pos = 0;
Siva Durga Prasad Paladugu1a897662014-03-14 16:35:37 +0530407 int fstype;
408 char *interface, *dev_part, *filename;
409
410 blocksize = fsinfo->blocksize;
411 interface = fsinfo->interface;
412 dev_part = fsinfo->dev_part;
413 filename = fsinfo->filename;
414 fstype = fsinfo->fstype;
415
416 if (fs_set_blk_dev(interface, dev_part, fstype))
417 return FPGA_FAIL;
418
Suriyan Ramasamid455d872014-11-17 14:39:38 -0800419 if (fs_read(filename, (u32) buf, pos, blocksize, &actread) < 0)
Siva Durga Prasad Paladugu1a897662014-03-14 16:35:37 +0530420 return FPGA_FAIL;
421
422 if (zynq_validate_bitstream(desc, buf, bsize, blocksize, &swap,
423 &partialbit))
424 return FPGA_FAIL;
425
426 dcache_disable();
427
428 do {
429 buf = zynq_align_dma_buffer((u32 *)buf, blocksize, swap);
430
431 if (zynq_dma_transfer((u32)buf | 1, blocksize >> 2,
432 0xffffffff, 0))
433 return FPGA_FAIL;
434
435 bsize -= blocksize;
436 pos += blocksize;
437
438 if (fs_set_blk_dev(interface, dev_part, fstype))
439 return FPGA_FAIL;
440
441 if (bsize > blocksize) {
Suriyan Ramasamid455d872014-11-17 14:39:38 -0800442 if (fs_read(filename, (u32) buf, pos, blocksize, &actread) < 0)
Siva Durga Prasad Paladugu1a897662014-03-14 16:35:37 +0530443 return FPGA_FAIL;
444 } else {
Suriyan Ramasamid455d872014-11-17 14:39:38 -0800445 if (fs_read(filename, (u32) buf, pos, bsize, &actread) < 0)
Siva Durga Prasad Paladugu1a897662014-03-14 16:35:37 +0530446 return FPGA_FAIL;
447 }
448 } while (bsize > blocksize);
449
450 buf = zynq_align_dma_buffer((u32 *)buf, blocksize, swap);
451
452 if (zynq_dma_transfer((u32)buf | 1, bsize >> 2, 0xffffffff, 0))
453 return FPGA_FAIL;
454
455 dcache_enable();
456
457 isr_status = readl(&devcfg_base->int_sts);
458
459 /* Check FPGA configuration completion */
460 ts = get_timer(0);
461 while (!(isr_status & DEVCFG_ISR_PCFG_DONE)) {
462 if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) {
463 printf("%s: Timeout wait for FPGA to config\n",
464 __func__);
465 return FPGA_FAIL;
466 }
467 isr_status = readl(&devcfg_base->int_sts);
468 }
469
470 debug("%s: FPGA config done\n", __func__);
471
472 if (!partialbit)
473 zynq_slcr_devcfg_enable();
474
475 return FPGA_SUCCESS;
476}
477#endif
478
Michal Simek14cfc4f2014-03-13 13:07:57 +0100479struct xilinx_fpga_op zynq_op = {
480 .load = zynq_load,
Siva Durga Prasad Paladugu1a897662014-03-14 16:35:37 +0530481#if defined(CONFIG_CMD_FPGA_LOADFS)
482 .loadfs = zynq_loadfs,
483#endif
Michal Simek14cfc4f2014-03-13 13:07:57 +0100484};