1d5dae85fSMichal Simek /* 2d5dae85fSMichal Simek * (C) Copyright 2012-2013, Xilinx, Michal Simek 3d5dae85fSMichal Simek * 4d5dae85fSMichal Simek * (C) Copyright 2012 5d5dae85fSMichal Simek * Joe Hershberger <joe.hershberger@ni.com> 6d5dae85fSMichal Simek * 71a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 8d5dae85fSMichal Simek */ 9d5dae85fSMichal Simek 10d5dae85fSMichal Simek #include <common.h> 11d5dae85fSMichal Simek #include <asm/io.h> 12d5dae85fSMichal Simek #include <zynqpl.h> 131ace4022SAlexey Brodkin #include <linux/sizes.h> 14d5dae85fSMichal Simek #include <asm/arch/hardware.h> 15d5dae85fSMichal Simek #include <asm/arch/sys_proto.h> 16d5dae85fSMichal Simek 17d5dae85fSMichal Simek #define DEVCFG_CTRL_PCFG_PROG_B 0x40000000 18d5dae85fSMichal Simek #define DEVCFG_ISR_FATAL_ERROR_MASK 0x00740040 19d5dae85fSMichal Simek #define DEVCFG_ISR_ERROR_FLAGS_MASK 0x00340840 20d5dae85fSMichal Simek #define DEVCFG_ISR_RX_FIFO_OV 0x00040000 21d5dae85fSMichal Simek #define DEVCFG_ISR_DMA_DONE 0x00002000 22d5dae85fSMichal Simek #define DEVCFG_ISR_PCFG_DONE 0x00000004 23d5dae85fSMichal Simek #define DEVCFG_STATUS_DMA_CMD_Q_F 0x80000000 24d5dae85fSMichal Simek #define DEVCFG_STATUS_DMA_CMD_Q_E 0x40000000 25d5dae85fSMichal Simek #define DEVCFG_STATUS_DMA_DONE_CNT_MASK 0x30000000 26d5dae85fSMichal Simek #define DEVCFG_STATUS_PCFG_INIT 0x00000010 275f93227cSSoren Brinkmann #define DEVCFG_MCTRL_PCAP_LPBK 0x00000010 28d5dae85fSMichal Simek #define DEVCFG_MCTRL_RFIFO_FLUSH 0x00000002 29d5dae85fSMichal Simek #define DEVCFG_MCTRL_WFIFO_FLUSH 0x00000001 30d5dae85fSMichal Simek 31d5dae85fSMichal Simek #ifndef CONFIG_SYS_FPGA_WAIT 32d5dae85fSMichal Simek #define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100 /* 10 ms */ 33d5dae85fSMichal Simek #endif 34d5dae85fSMichal Simek 35d5dae85fSMichal Simek #ifndef CONFIG_SYS_FPGA_PROG_TIME 36fd2b10b6SMichal Simek #define CONFIG_SYS_FPGA_PROG_TIME (CONFIG_SYS_HZ * 4) /* 4 s */ 37d5dae85fSMichal Simek #endif 38d5dae85fSMichal Simek 3914cfc4f3SMichal Simek static int zynq_info(xilinx_desc *desc) 40d5dae85fSMichal Simek { 41d5dae85fSMichal Simek return FPGA_SUCCESS; 42d5dae85fSMichal Simek } 43d5dae85fSMichal Simek 44d5dae85fSMichal Simek #define DUMMY_WORD 0xffffffff 45d5dae85fSMichal Simek 46d5dae85fSMichal Simek /* Xilinx binary format header */ 47d5dae85fSMichal Simek static const u32 bin_format[] = { 48d5dae85fSMichal Simek DUMMY_WORD, /* Dummy words */ 49d5dae85fSMichal Simek DUMMY_WORD, 50d5dae85fSMichal Simek DUMMY_WORD, 51d5dae85fSMichal Simek DUMMY_WORD, 52d5dae85fSMichal Simek DUMMY_WORD, 53d5dae85fSMichal Simek DUMMY_WORD, 54d5dae85fSMichal Simek DUMMY_WORD, 55d5dae85fSMichal Simek DUMMY_WORD, 56d5dae85fSMichal Simek 0x000000bb, /* Sync word */ 57d5dae85fSMichal Simek 0x11220044, /* Sync word */ 58d5dae85fSMichal Simek DUMMY_WORD, 59d5dae85fSMichal Simek DUMMY_WORD, 60d5dae85fSMichal Simek 0xaa995566, /* Sync word */ 61d5dae85fSMichal Simek }; 62d5dae85fSMichal Simek 63d5dae85fSMichal Simek #define SWAP_NO 1 64d5dae85fSMichal Simek #define SWAP_DONE 2 65d5dae85fSMichal Simek 66d5dae85fSMichal Simek /* 67d5dae85fSMichal Simek * Load the whole word from unaligned buffer 68d5dae85fSMichal Simek * Keep in your mind that it is byte loading on little-endian system 69d5dae85fSMichal Simek */ 70d5dae85fSMichal Simek static u32 load_word(const void *buf, u32 swap) 71d5dae85fSMichal Simek { 72d5dae85fSMichal Simek u32 word = 0; 73d5dae85fSMichal Simek u8 *bitc = (u8 *)buf; 74d5dae85fSMichal Simek int p; 75d5dae85fSMichal Simek 76d5dae85fSMichal Simek if (swap == SWAP_NO) { 77d5dae85fSMichal Simek for (p = 0; p < 4; p++) { 78d5dae85fSMichal Simek word <<= 8; 79d5dae85fSMichal Simek word |= bitc[p]; 80d5dae85fSMichal Simek } 81d5dae85fSMichal Simek } else { 82d5dae85fSMichal Simek for (p = 3; p >= 0; p--) { 83d5dae85fSMichal Simek word <<= 8; 84d5dae85fSMichal Simek word |= bitc[p]; 85d5dae85fSMichal Simek } 86d5dae85fSMichal Simek } 87d5dae85fSMichal Simek 88d5dae85fSMichal Simek return word; 89d5dae85fSMichal Simek } 90d5dae85fSMichal Simek 91d5dae85fSMichal Simek static u32 check_header(const void *buf) 92d5dae85fSMichal Simek { 93d5dae85fSMichal Simek u32 i, pattern; 94d5dae85fSMichal Simek int swap = SWAP_NO; 95d5dae85fSMichal Simek u32 *test = (u32 *)buf; 96d5dae85fSMichal Simek 97d5dae85fSMichal Simek debug("%s: Let's check bitstream header\n", __func__); 98d5dae85fSMichal Simek 99d5dae85fSMichal Simek /* Checking that passing bin is not a bitstream */ 100d5dae85fSMichal Simek for (i = 0; i < ARRAY_SIZE(bin_format); i++) { 101d5dae85fSMichal Simek pattern = load_word(&test[i], swap); 102d5dae85fSMichal Simek 103d5dae85fSMichal Simek /* 104d5dae85fSMichal Simek * Bitstreams in binary format are swapped 105d5dae85fSMichal Simek * compare to regular bistream. 106d5dae85fSMichal Simek * Do not swap dummy word but if swap is done assume 107d5dae85fSMichal Simek * that parsing buffer is binary format 108d5dae85fSMichal Simek */ 109d5dae85fSMichal Simek if ((__swab32(pattern) != DUMMY_WORD) && 110d5dae85fSMichal Simek (__swab32(pattern) == bin_format[i])) { 111d5dae85fSMichal Simek pattern = __swab32(pattern); 112d5dae85fSMichal Simek swap = SWAP_DONE; 113d5dae85fSMichal Simek debug("%s: data swapped - let's swap\n", __func__); 114d5dae85fSMichal Simek } 115d5dae85fSMichal Simek 116d5dae85fSMichal Simek debug("%s: %d/%x: pattern %x/%x bin_format\n", __func__, i, 117d5dae85fSMichal Simek (u32)&test[i], pattern, bin_format[i]); 118d5dae85fSMichal Simek if (pattern != bin_format[i]) { 119d5dae85fSMichal Simek debug("%s: Bitstream is not recognized\n", __func__); 120d5dae85fSMichal Simek return 0; 121d5dae85fSMichal Simek } 122d5dae85fSMichal Simek } 123d5dae85fSMichal Simek debug("%s: Found bitstream header at %x %s swapinng\n", __func__, 124d5dae85fSMichal Simek (u32)buf, swap == SWAP_NO ? "without" : "with"); 125d5dae85fSMichal Simek 126d5dae85fSMichal Simek return swap; 127d5dae85fSMichal Simek } 128d5dae85fSMichal Simek 129d5dae85fSMichal Simek static void *check_data(u8 *buf, size_t bsize, u32 *swap) 130d5dae85fSMichal Simek { 131d5dae85fSMichal Simek u32 word, p = 0; /* possition */ 132d5dae85fSMichal Simek 133d5dae85fSMichal Simek /* Because buf doesn't need to be aligned let's read it by chars */ 134d5dae85fSMichal Simek for (p = 0; p < bsize; p++) { 135d5dae85fSMichal Simek word = load_word(&buf[p], SWAP_NO); 136d5dae85fSMichal Simek debug("%s: word %x %x/%x\n", __func__, word, p, (u32)&buf[p]); 137d5dae85fSMichal Simek 138d5dae85fSMichal Simek /* Find the first bitstream dummy word */ 139d5dae85fSMichal Simek if (word == DUMMY_WORD) { 140d5dae85fSMichal Simek debug("%s: Found dummy word at position %x/%x\n", 141d5dae85fSMichal Simek __func__, p, (u32)&buf[p]); 142d5dae85fSMichal Simek *swap = check_header(&buf[p]); 143d5dae85fSMichal Simek if (*swap) { 144d5dae85fSMichal Simek /* FIXME add full bitstream checking here */ 145d5dae85fSMichal Simek return &buf[p]; 146d5dae85fSMichal Simek } 147d5dae85fSMichal Simek } 148d5dae85fSMichal Simek /* Loop can be huge - support CTRL + C */ 149d5dae85fSMichal Simek if (ctrlc()) 15042a74a08SMichal Simek return NULL; 151d5dae85fSMichal Simek } 15242a74a08SMichal Simek return NULL; 153d5dae85fSMichal Simek } 154d5dae85fSMichal Simek 155*a0735a34SSiva Durga Prasad Paladugu static int zynq_dma_transfer(u32 srcbuf, u32 srclen, u32 dstbuf, u32 dstlen) 156d5dae85fSMichal Simek { 157*a0735a34SSiva Durga Prasad Paladugu unsigned long ts; 158*a0735a34SSiva Durga Prasad Paladugu u32 isr_status; 159d5dae85fSMichal Simek 160*a0735a34SSiva Durga Prasad Paladugu /* Set up the transfer */ 161*a0735a34SSiva Durga Prasad Paladugu writel((u32)srcbuf, &devcfg_base->dma_src_addr); 162*a0735a34SSiva Durga Prasad Paladugu writel(dstbuf, &devcfg_base->dma_dst_addr); 163*a0735a34SSiva Durga Prasad Paladugu writel(srclen, &devcfg_base->dma_src_len); 164*a0735a34SSiva Durga Prasad Paladugu writel(dstlen, &devcfg_base->dma_dst_len); 165d5dae85fSMichal Simek 166*a0735a34SSiva Durga Prasad Paladugu isr_status = readl(&devcfg_base->int_sts); 167d5dae85fSMichal Simek 168*a0735a34SSiva Durga Prasad Paladugu /* Polling the PCAP_INIT status for Set */ 169*a0735a34SSiva Durga Prasad Paladugu ts = get_timer(0); 170*a0735a34SSiva Durga Prasad Paladugu while (!(isr_status & DEVCFG_ISR_DMA_DONE)) { 171*a0735a34SSiva Durga Prasad Paladugu if (isr_status & DEVCFG_ISR_ERROR_FLAGS_MASK) { 172*a0735a34SSiva Durga Prasad Paladugu debug("%s: Error: isr = 0x%08X\n", __func__, 173*a0735a34SSiva Durga Prasad Paladugu isr_status); 174*a0735a34SSiva Durga Prasad Paladugu debug("%s: Write count = 0x%08X\n", __func__, 175*a0735a34SSiva Durga Prasad Paladugu readl(&devcfg_base->write_count)); 176*a0735a34SSiva Durga Prasad Paladugu debug("%s: Read count = 0x%08X\n", __func__, 177*a0735a34SSiva Durga Prasad Paladugu readl(&devcfg_base->read_count)); 178*a0735a34SSiva Durga Prasad Paladugu 179d5dae85fSMichal Simek return FPGA_FAIL; 180d5dae85fSMichal Simek } 181*a0735a34SSiva Durga Prasad Paladugu if (get_timer(ts) > CONFIG_SYS_FPGA_PROG_TIME) { 182*a0735a34SSiva Durga Prasad Paladugu printf("%s: Timeout wait for DMA to complete\n", 183c83a35f6SNovasys Ingenierie __func__); 184*a0735a34SSiva Durga Prasad Paladugu return FPGA_FAIL; 185*a0735a34SSiva Durga Prasad Paladugu } 186*a0735a34SSiva Durga Prasad Paladugu isr_status = readl(&devcfg_base->int_sts); 187c83a35f6SNovasys Ingenierie } 188c83a35f6SNovasys Ingenierie 189*a0735a34SSiva Durga Prasad Paladugu debug("%s: DMA transfer is done\n", __func__); 190d5dae85fSMichal Simek 191*a0735a34SSiva Durga Prasad Paladugu /* Clear out the DMA status */ 192*a0735a34SSiva Durga Prasad Paladugu writel(DEVCFG_ISR_DMA_DONE, &devcfg_base->int_sts); 193d5dae85fSMichal Simek 194*a0735a34SSiva Durga Prasad Paladugu return FPGA_SUCCESS; 195d5dae85fSMichal Simek } 196d5dae85fSMichal Simek 197*a0735a34SSiva Durga Prasad Paladugu static int zynq_dma_xfer_init(u32 partialbit) 198*a0735a34SSiva Durga Prasad Paladugu { 199*a0735a34SSiva Durga Prasad Paladugu u32 status, control, isr_status; 200*a0735a34SSiva Durga Prasad Paladugu unsigned long ts; 201*a0735a34SSiva Durga Prasad Paladugu 2025f93227cSSoren Brinkmann /* Clear loopback bit */ 2035f93227cSSoren Brinkmann clrbits_le32(&devcfg_base->mctrl, DEVCFG_MCTRL_PCAP_LPBK); 2045f93227cSSoren Brinkmann 205d5dae85fSMichal Simek if (!partialbit) { 206d5dae85fSMichal Simek zynq_slcr_devcfg_disable(); 207d5dae85fSMichal Simek 208d5dae85fSMichal Simek /* Setting PCFG_PROG_B signal to high */ 209d5dae85fSMichal Simek control = readl(&devcfg_base->ctrl); 210d5dae85fSMichal Simek writel(control | DEVCFG_CTRL_PCFG_PROG_B, &devcfg_base->ctrl); 211d5dae85fSMichal Simek /* Setting PCFG_PROG_B signal to low */ 212d5dae85fSMichal Simek writel(control & ~DEVCFG_CTRL_PCFG_PROG_B, &devcfg_base->ctrl); 213d5dae85fSMichal Simek 214d5dae85fSMichal Simek /* Polling the PCAP_INIT status for Reset */ 215d5dae85fSMichal Simek ts = get_timer(0); 216d5dae85fSMichal Simek while (readl(&devcfg_base->status) & DEVCFG_STATUS_PCFG_INIT) { 217d5dae85fSMichal Simek if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) { 218d5dae85fSMichal Simek printf("%s: Timeout wait for INIT to clear\n", 219d5dae85fSMichal Simek __func__); 220d5dae85fSMichal Simek return FPGA_FAIL; 221d5dae85fSMichal Simek } 222d5dae85fSMichal Simek } 223d5dae85fSMichal Simek 224d5dae85fSMichal Simek /* Setting PCFG_PROG_B signal to high */ 225d5dae85fSMichal Simek writel(control | DEVCFG_CTRL_PCFG_PROG_B, &devcfg_base->ctrl); 226d5dae85fSMichal Simek 227d5dae85fSMichal Simek /* Polling the PCAP_INIT status for Set */ 228d5dae85fSMichal Simek ts = get_timer(0); 229d5dae85fSMichal Simek while (!(readl(&devcfg_base->status) & 230d5dae85fSMichal Simek DEVCFG_STATUS_PCFG_INIT)) { 231d5dae85fSMichal Simek if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) { 232d5dae85fSMichal Simek printf("%s: Timeout wait for INIT to set\n", 233d5dae85fSMichal Simek __func__); 234d5dae85fSMichal Simek return FPGA_FAIL; 235d5dae85fSMichal Simek } 236d5dae85fSMichal Simek } 237d5dae85fSMichal Simek } 238d5dae85fSMichal Simek 239d5dae85fSMichal Simek isr_status = readl(&devcfg_base->int_sts); 240d5dae85fSMichal Simek 241d5dae85fSMichal Simek /* Clear it all, so if Boot ROM comes back, it can proceed */ 242d5dae85fSMichal Simek writel(0xFFFFFFFF, &devcfg_base->int_sts); 243d5dae85fSMichal Simek 244d5dae85fSMichal Simek if (isr_status & DEVCFG_ISR_FATAL_ERROR_MASK) { 245d5dae85fSMichal Simek debug("%s: Fatal errors in PCAP 0x%X\n", __func__, isr_status); 246d5dae85fSMichal Simek 247d5dae85fSMichal Simek /* If RX FIFO overflow, need to flush RX FIFO first */ 248d5dae85fSMichal Simek if (isr_status & DEVCFG_ISR_RX_FIFO_OV) { 249d5dae85fSMichal Simek writel(DEVCFG_MCTRL_RFIFO_FLUSH, &devcfg_base->mctrl); 250d5dae85fSMichal Simek writel(0xFFFFFFFF, &devcfg_base->int_sts); 251d5dae85fSMichal Simek } 252d5dae85fSMichal Simek return FPGA_FAIL; 253d5dae85fSMichal Simek } 254d5dae85fSMichal Simek 255d5dae85fSMichal Simek status = readl(&devcfg_base->status); 256d5dae85fSMichal Simek 257d5dae85fSMichal Simek debug("%s: Status = 0x%08X\n", __func__, status); 258d5dae85fSMichal Simek 259d5dae85fSMichal Simek if (status & DEVCFG_STATUS_DMA_CMD_Q_F) { 260d5dae85fSMichal Simek debug("%s: Error: device busy\n", __func__); 261d5dae85fSMichal Simek return FPGA_FAIL; 262d5dae85fSMichal Simek } 263d5dae85fSMichal Simek 264d5dae85fSMichal Simek debug("%s: Device ready\n", __func__); 265d5dae85fSMichal Simek 266d5dae85fSMichal Simek if (!(status & DEVCFG_STATUS_DMA_CMD_Q_E)) { 267d5dae85fSMichal Simek if (!(readl(&devcfg_base->int_sts) & DEVCFG_ISR_DMA_DONE)) { 268d5dae85fSMichal Simek /* Error state, transfer cannot occur */ 269d5dae85fSMichal Simek debug("%s: ISR indicates error\n", __func__); 270d5dae85fSMichal Simek return FPGA_FAIL; 271d5dae85fSMichal Simek } else { 272d5dae85fSMichal Simek /* Clear out the status */ 273d5dae85fSMichal Simek writel(DEVCFG_ISR_DMA_DONE, &devcfg_base->int_sts); 274d5dae85fSMichal Simek } 275d5dae85fSMichal Simek } 276d5dae85fSMichal Simek 277d5dae85fSMichal Simek if (status & DEVCFG_STATUS_DMA_DONE_CNT_MASK) { 278d5dae85fSMichal Simek /* Clear the count of completed DMA transfers */ 279d5dae85fSMichal Simek writel(DEVCFG_STATUS_DMA_DONE_CNT_MASK, &devcfg_base->status); 280d5dae85fSMichal Simek } 281d5dae85fSMichal Simek 282*a0735a34SSiva Durga Prasad Paladugu return FPGA_SUCCESS; 283*a0735a34SSiva Durga Prasad Paladugu } 284*a0735a34SSiva Durga Prasad Paladugu 285*a0735a34SSiva Durga Prasad Paladugu static u32 *zynq_align_dma_buffer(u32 *buf, u32 len, u32 swap) 286*a0735a34SSiva Durga Prasad Paladugu { 287*a0735a34SSiva Durga Prasad Paladugu u32 *new_buf; 288*a0735a34SSiva Durga Prasad Paladugu u32 i; 289*a0735a34SSiva Durga Prasad Paladugu 290*a0735a34SSiva Durga Prasad Paladugu if ((u32)buf != ALIGN((u32)buf, ARCH_DMA_MINALIGN)) { 291*a0735a34SSiva Durga Prasad Paladugu new_buf = (u32 *)ALIGN((u32)buf, ARCH_DMA_MINALIGN); 292*a0735a34SSiva Durga Prasad Paladugu 293*a0735a34SSiva Durga Prasad Paladugu /* 294*a0735a34SSiva Durga Prasad Paladugu * This might be dangerous but permits to flash if 295*a0735a34SSiva Durga Prasad Paladugu * ARCH_DMA_MINALIGN is greater than header size 296*a0735a34SSiva Durga Prasad Paladugu */ 297*a0735a34SSiva Durga Prasad Paladugu if (new_buf > buf) { 298*a0735a34SSiva Durga Prasad Paladugu debug("%s: Aligned buffer is after buffer start\n", 299*a0735a34SSiva Durga Prasad Paladugu __func__); 300*a0735a34SSiva Durga Prasad Paladugu new_buf -= ARCH_DMA_MINALIGN; 301*a0735a34SSiva Durga Prasad Paladugu } 302*a0735a34SSiva Durga Prasad Paladugu printf("%s: Align buffer at %x to %x(swap %d)\n", __func__, 303*a0735a34SSiva Durga Prasad Paladugu (u32)buf, (u32)new_buf, swap); 304*a0735a34SSiva Durga Prasad Paladugu 305*a0735a34SSiva Durga Prasad Paladugu for (i = 0; i < (len/4); i++) 306*a0735a34SSiva Durga Prasad Paladugu new_buf[i] = load_word(&buf[i], swap); 307*a0735a34SSiva Durga Prasad Paladugu 308*a0735a34SSiva Durga Prasad Paladugu buf = new_buf; 309*a0735a34SSiva Durga Prasad Paladugu } else if (swap != SWAP_DONE) { 310*a0735a34SSiva Durga Prasad Paladugu /* For bitstream which are aligned */ 311*a0735a34SSiva Durga Prasad Paladugu u32 *new_buf = (u32 *)buf; 312*a0735a34SSiva Durga Prasad Paladugu 313*a0735a34SSiva Durga Prasad Paladugu printf("%s: Bitstream is not swapped(%d) - swap it\n", __func__, 314*a0735a34SSiva Durga Prasad Paladugu swap); 315*a0735a34SSiva Durga Prasad Paladugu 316*a0735a34SSiva Durga Prasad Paladugu for (i = 0; i < (len/4); i++) 317*a0735a34SSiva Durga Prasad Paladugu new_buf[i] = load_word(&buf[i], swap); 318*a0735a34SSiva Durga Prasad Paladugu } 319*a0735a34SSiva Durga Prasad Paladugu 320*a0735a34SSiva Durga Prasad Paladugu return buf; 321*a0735a34SSiva Durga Prasad Paladugu } 322*a0735a34SSiva Durga Prasad Paladugu 323*a0735a34SSiva Durga Prasad Paladugu static int zynq_load(xilinx_desc *desc, const void *buf, size_t bsize) 324*a0735a34SSiva Durga Prasad Paladugu { 325*a0735a34SSiva Durga Prasad Paladugu unsigned long ts; /* Timestamp */ 326*a0735a34SSiva Durga Prasad Paladugu u32 partialbit = 0; 327*a0735a34SSiva Durga Prasad Paladugu u32 isr_status, swap, diff; 328*a0735a34SSiva Durga Prasad Paladugu u32 *buf_start; 329*a0735a34SSiva Durga Prasad Paladugu 330*a0735a34SSiva Durga Prasad Paladugu /* Detect if we are going working with partial or full bitstream */ 331*a0735a34SSiva Durga Prasad Paladugu if (bsize != desc->size) { 332*a0735a34SSiva Durga Prasad Paladugu printf("%s: Working with partial bitstream\n", __func__); 333*a0735a34SSiva Durga Prasad Paladugu partialbit = 1; 334*a0735a34SSiva Durga Prasad Paladugu } 335*a0735a34SSiva Durga Prasad Paladugu 336*a0735a34SSiva Durga Prasad Paladugu buf_start = check_data((u8 *)buf, bsize, &swap); 337*a0735a34SSiva Durga Prasad Paladugu if (!buf_start) 338*a0735a34SSiva Durga Prasad Paladugu return FPGA_FAIL; 339*a0735a34SSiva Durga Prasad Paladugu 340*a0735a34SSiva Durga Prasad Paladugu /* Check if data is postpone from start */ 341*a0735a34SSiva Durga Prasad Paladugu diff = (u32)buf_start - (u32)buf; 342*a0735a34SSiva Durga Prasad Paladugu if (diff) { 343*a0735a34SSiva Durga Prasad Paladugu printf("%s: Bitstream is not validated yet (diff %x)\n", 344*a0735a34SSiva Durga Prasad Paladugu __func__, diff); 345*a0735a34SSiva Durga Prasad Paladugu return FPGA_FAIL; 346*a0735a34SSiva Durga Prasad Paladugu } 347*a0735a34SSiva Durga Prasad Paladugu 348*a0735a34SSiva Durga Prasad Paladugu if ((u32)buf < SZ_1M) { 349*a0735a34SSiva Durga Prasad Paladugu printf("%s: Bitstream has to be placed up to 1MB (%x)\n", 350*a0735a34SSiva Durga Prasad Paladugu __func__, (u32)buf); 351*a0735a34SSiva Durga Prasad Paladugu return FPGA_FAIL; 352*a0735a34SSiva Durga Prasad Paladugu } 353*a0735a34SSiva Durga Prasad Paladugu 354*a0735a34SSiva Durga Prasad Paladugu if (zynq_dma_xfer_init(partialbit)) 355*a0735a34SSiva Durga Prasad Paladugu return FPGA_FAIL; 356*a0735a34SSiva Durga Prasad Paladugu 357*a0735a34SSiva Durga Prasad Paladugu buf = zynq_align_dma_buffer((u32 *)buf, bsize, swap); 358*a0735a34SSiva Durga Prasad Paladugu 359d5dae85fSMichal Simek debug("%s: Source = 0x%08X\n", __func__, (u32)buf); 360d5dae85fSMichal Simek debug("%s: Size = %zu\n", __func__, bsize); 361d5dae85fSMichal Simek 362ec4b73f0SJagannadha Sutradharudu Teki /* flush(clean & invalidate) d-cache range buf */ 363ec4b73f0SJagannadha Sutradharudu Teki flush_dcache_range((u32)buf, (u32)buf + 364ec4b73f0SJagannadha Sutradharudu Teki roundup(bsize, ARCH_DMA_MINALIGN)); 365ec4b73f0SJagannadha Sutradharudu Teki 366*a0735a34SSiva Durga Prasad Paladugu if (zynq_dma_transfer((u32)buf | 1, bsize >> 2, 0xffffffff, 0)) 367*a0735a34SSiva Durga Prasad Paladugu return FPGA_FAIL; 368d5dae85fSMichal Simek 369d5dae85fSMichal Simek isr_status = readl(&devcfg_base->int_sts); 370d5dae85fSMichal Simek /* Check FPGA configuration completion */ 371d5dae85fSMichal Simek ts = get_timer(0); 372d5dae85fSMichal Simek while (!(isr_status & DEVCFG_ISR_PCFG_DONE)) { 373d5dae85fSMichal Simek if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) { 374d5dae85fSMichal Simek printf("%s: Timeout wait for FPGA to config\n", 375d5dae85fSMichal Simek __func__); 376d5dae85fSMichal Simek return FPGA_FAIL; 377d5dae85fSMichal Simek } 378d5dae85fSMichal Simek isr_status = readl(&devcfg_base->int_sts); 379d5dae85fSMichal Simek } 380d5dae85fSMichal Simek 381d5dae85fSMichal Simek debug("%s: FPGA config done\n", __func__); 382d5dae85fSMichal Simek 383d5dae85fSMichal Simek if (!partialbit) 384d5dae85fSMichal Simek zynq_slcr_devcfg_enable(); 385d5dae85fSMichal Simek 386d5dae85fSMichal Simek return FPGA_SUCCESS; 387d5dae85fSMichal Simek } 388d5dae85fSMichal Simek 38914cfc4f3SMichal Simek static int zynq_dump(xilinx_desc *desc, const void *buf, size_t bsize) 390d5dae85fSMichal Simek { 391d5dae85fSMichal Simek return FPGA_FAIL; 392d5dae85fSMichal Simek } 39314cfc4f3SMichal Simek 39414cfc4f3SMichal Simek struct xilinx_fpga_op zynq_op = { 39514cfc4f3SMichal Simek .load = zynq_load, 39614cfc4f3SMichal Simek .dump = zynq_dump, 39714cfc4f3SMichal Simek .info = zynq_info, 39814cfc4f3SMichal Simek }; 399