1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+ 2d5dae85fSMichal Simek /* 3d5dae85fSMichal Simek * (C) Copyright 2012-2013, Xilinx, Michal Simek 4d5dae85fSMichal Simek * 5d5dae85fSMichal Simek * (C) Copyright 2012 6d5dae85fSMichal Simek * Joe Hershberger <joe.hershberger@ni.com> 7d5dae85fSMichal Simek */ 8d5dae85fSMichal Simek 9d5dae85fSMichal Simek #include <common.h> 1024b852a7SSimon Glass #include <console.h> 11d5dae85fSMichal Simek #include <asm/io.h> 121a897668SSiva Durga Prasad Paladugu #include <fs.h> 13d5dae85fSMichal Simek #include <zynqpl.h> 141ace4022SAlexey Brodkin #include <linux/sizes.h> 15d5dae85fSMichal Simek #include <asm/arch/hardware.h> 16d5dae85fSMichal Simek #include <asm/arch/sys_proto.h> 17d5dae85fSMichal Simek 18d5dae85fSMichal Simek #define DEVCFG_CTRL_PCFG_PROG_B 0x40000000 1971723aaeSSiva Durga Prasad Paladugu #define DEVCFG_CTRL_PCFG_AES_EFUSE_MASK 0x00001000 20d5dae85fSMichal Simek #define DEVCFG_ISR_FATAL_ERROR_MASK 0x00740040 21d5dae85fSMichal Simek #define DEVCFG_ISR_ERROR_FLAGS_MASK 0x00340840 22d5dae85fSMichal Simek #define DEVCFG_ISR_RX_FIFO_OV 0x00040000 23d5dae85fSMichal Simek #define DEVCFG_ISR_DMA_DONE 0x00002000 24d5dae85fSMichal Simek #define DEVCFG_ISR_PCFG_DONE 0x00000004 25d5dae85fSMichal Simek #define DEVCFG_STATUS_DMA_CMD_Q_F 0x80000000 26d5dae85fSMichal Simek #define DEVCFG_STATUS_DMA_CMD_Q_E 0x40000000 27d5dae85fSMichal Simek #define DEVCFG_STATUS_DMA_DONE_CNT_MASK 0x30000000 28d5dae85fSMichal Simek #define DEVCFG_STATUS_PCFG_INIT 0x00000010 295f93227cSSoren Brinkmann #define DEVCFG_MCTRL_PCAP_LPBK 0x00000010 30d5dae85fSMichal Simek #define DEVCFG_MCTRL_RFIFO_FLUSH 0x00000002 31d5dae85fSMichal Simek #define DEVCFG_MCTRL_WFIFO_FLUSH 0x00000001 32d5dae85fSMichal Simek 33d5dae85fSMichal Simek #ifndef CONFIG_SYS_FPGA_WAIT 34d5dae85fSMichal Simek #define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100 /* 10 ms */ 35d5dae85fSMichal Simek #endif 36d5dae85fSMichal Simek 37d5dae85fSMichal Simek #ifndef CONFIG_SYS_FPGA_PROG_TIME 38fd2b10b6SMichal Simek #define CONFIG_SYS_FPGA_PROG_TIME (CONFIG_SYS_HZ * 4) /* 4 s */ 39d5dae85fSMichal Simek #endif 40d5dae85fSMichal Simek 41d5dae85fSMichal Simek #define DUMMY_WORD 0xffffffff 42d5dae85fSMichal Simek 43d5dae85fSMichal Simek /* Xilinx binary format header */ 44d5dae85fSMichal Simek static const u32 bin_format[] = { 45d5dae85fSMichal Simek DUMMY_WORD, /* Dummy words */ 46d5dae85fSMichal Simek DUMMY_WORD, 47d5dae85fSMichal Simek DUMMY_WORD, 48d5dae85fSMichal Simek DUMMY_WORD, 49d5dae85fSMichal Simek DUMMY_WORD, 50d5dae85fSMichal Simek DUMMY_WORD, 51d5dae85fSMichal Simek DUMMY_WORD, 52d5dae85fSMichal Simek DUMMY_WORD, 53d5dae85fSMichal Simek 0x000000bb, /* Sync word */ 54d5dae85fSMichal Simek 0x11220044, /* Sync word */ 55d5dae85fSMichal Simek DUMMY_WORD, 56d5dae85fSMichal Simek DUMMY_WORD, 57d5dae85fSMichal Simek 0xaa995566, /* Sync word */ 58d5dae85fSMichal Simek }; 59d5dae85fSMichal Simek 60d5dae85fSMichal Simek #define SWAP_NO 1 61d5dae85fSMichal Simek #define SWAP_DONE 2 62d5dae85fSMichal Simek 63d5dae85fSMichal Simek /* 64d5dae85fSMichal Simek * Load the whole word from unaligned buffer 65d5dae85fSMichal Simek * Keep in your mind that it is byte loading on little-endian system 66d5dae85fSMichal Simek */ 67d5dae85fSMichal Simek static u32 load_word(const void *buf, u32 swap) 68d5dae85fSMichal Simek { 69d5dae85fSMichal Simek u32 word = 0; 70d5dae85fSMichal Simek u8 *bitc = (u8 *)buf; 71d5dae85fSMichal Simek int p; 72d5dae85fSMichal Simek 73d5dae85fSMichal Simek if (swap == SWAP_NO) { 74d5dae85fSMichal Simek for (p = 0; p < 4; p++) { 75d5dae85fSMichal Simek word <<= 8; 76d5dae85fSMichal Simek word |= bitc[p]; 77d5dae85fSMichal Simek } 78d5dae85fSMichal Simek } else { 79d5dae85fSMichal Simek for (p = 3; p >= 0; p--) { 80d5dae85fSMichal Simek word <<= 8; 81d5dae85fSMichal Simek word |= bitc[p]; 82d5dae85fSMichal Simek } 83d5dae85fSMichal Simek } 84d5dae85fSMichal Simek 85d5dae85fSMichal Simek return word; 86d5dae85fSMichal Simek } 87d5dae85fSMichal Simek 88d5dae85fSMichal Simek static u32 check_header(const void *buf) 89d5dae85fSMichal Simek { 90d5dae85fSMichal Simek u32 i, pattern; 91d5dae85fSMichal Simek int swap = SWAP_NO; 92d5dae85fSMichal Simek u32 *test = (u32 *)buf; 93d5dae85fSMichal Simek 94d5dae85fSMichal Simek debug("%s: Let's check bitstream header\n", __func__); 95d5dae85fSMichal Simek 96d5dae85fSMichal Simek /* Checking that passing bin is not a bitstream */ 97d5dae85fSMichal Simek for (i = 0; i < ARRAY_SIZE(bin_format); i++) { 98d5dae85fSMichal Simek pattern = load_word(&test[i], swap); 99d5dae85fSMichal Simek 100d5dae85fSMichal Simek /* 101d5dae85fSMichal Simek * Bitstreams in binary format are swapped 102d5dae85fSMichal Simek * compare to regular bistream. 103d5dae85fSMichal Simek * Do not swap dummy word but if swap is done assume 104d5dae85fSMichal Simek * that parsing buffer is binary format 105d5dae85fSMichal Simek */ 106d5dae85fSMichal Simek if ((__swab32(pattern) != DUMMY_WORD) && 107d5dae85fSMichal Simek (__swab32(pattern) == bin_format[i])) { 108d5dae85fSMichal Simek pattern = __swab32(pattern); 109d5dae85fSMichal Simek swap = SWAP_DONE; 110d5dae85fSMichal Simek debug("%s: data swapped - let's swap\n", __func__); 111d5dae85fSMichal Simek } 112d5dae85fSMichal Simek 113d5dae85fSMichal Simek debug("%s: %d/%x: pattern %x/%x bin_format\n", __func__, i, 114d5dae85fSMichal Simek (u32)&test[i], pattern, bin_format[i]); 115d5dae85fSMichal Simek if (pattern != bin_format[i]) { 116d5dae85fSMichal Simek debug("%s: Bitstream is not recognized\n", __func__); 117d5dae85fSMichal Simek return 0; 118d5dae85fSMichal Simek } 119d5dae85fSMichal Simek } 120d5dae85fSMichal Simek debug("%s: Found bitstream header at %x %s swapinng\n", __func__, 121d5dae85fSMichal Simek (u32)buf, swap == SWAP_NO ? "without" : "with"); 122d5dae85fSMichal Simek 123d5dae85fSMichal Simek return swap; 124d5dae85fSMichal Simek } 125d5dae85fSMichal Simek 126d5dae85fSMichal Simek static void *check_data(u8 *buf, size_t bsize, u32 *swap) 127d5dae85fSMichal Simek { 128d5dae85fSMichal Simek u32 word, p = 0; /* possition */ 129d5dae85fSMichal Simek 130d5dae85fSMichal Simek /* Because buf doesn't need to be aligned let's read it by chars */ 131d5dae85fSMichal Simek for (p = 0; p < bsize; p++) { 132d5dae85fSMichal Simek word = load_word(&buf[p], SWAP_NO); 133d5dae85fSMichal Simek debug("%s: word %x %x/%x\n", __func__, word, p, (u32)&buf[p]); 134d5dae85fSMichal Simek 135d5dae85fSMichal Simek /* Find the first bitstream dummy word */ 136d5dae85fSMichal Simek if (word == DUMMY_WORD) { 137d5dae85fSMichal Simek debug("%s: Found dummy word at position %x/%x\n", 138d5dae85fSMichal Simek __func__, p, (u32)&buf[p]); 139d5dae85fSMichal Simek *swap = check_header(&buf[p]); 140d5dae85fSMichal Simek if (*swap) { 141d5dae85fSMichal Simek /* FIXME add full bitstream checking here */ 142d5dae85fSMichal Simek return &buf[p]; 143d5dae85fSMichal Simek } 144d5dae85fSMichal Simek } 145d5dae85fSMichal Simek /* Loop can be huge - support CTRL + C */ 146d5dae85fSMichal Simek if (ctrlc()) 14742a74a08SMichal Simek return NULL; 148d5dae85fSMichal Simek } 14942a74a08SMichal Simek return NULL; 150d5dae85fSMichal Simek } 151d5dae85fSMichal Simek 152a0735a34SSiva Durga Prasad Paladugu static int zynq_dma_transfer(u32 srcbuf, u32 srclen, u32 dstbuf, u32 dstlen) 153d5dae85fSMichal Simek { 154a0735a34SSiva Durga Prasad Paladugu unsigned long ts; 155a0735a34SSiva Durga Prasad Paladugu u32 isr_status; 156d5dae85fSMichal Simek 157a0735a34SSiva Durga Prasad Paladugu /* Set up the transfer */ 158a0735a34SSiva Durga Prasad Paladugu writel((u32)srcbuf, &devcfg_base->dma_src_addr); 159a0735a34SSiva Durga Prasad Paladugu writel(dstbuf, &devcfg_base->dma_dst_addr); 160a0735a34SSiva Durga Prasad Paladugu writel(srclen, &devcfg_base->dma_src_len); 161a0735a34SSiva Durga Prasad Paladugu writel(dstlen, &devcfg_base->dma_dst_len); 162d5dae85fSMichal Simek 163a0735a34SSiva Durga Prasad Paladugu isr_status = readl(&devcfg_base->int_sts); 164d5dae85fSMichal Simek 165a0735a34SSiva Durga Prasad Paladugu /* Polling the PCAP_INIT status for Set */ 166a0735a34SSiva Durga Prasad Paladugu ts = get_timer(0); 167a0735a34SSiva Durga Prasad Paladugu while (!(isr_status & DEVCFG_ISR_DMA_DONE)) { 168a0735a34SSiva Durga Prasad Paladugu if (isr_status & DEVCFG_ISR_ERROR_FLAGS_MASK) { 169a0735a34SSiva Durga Prasad Paladugu debug("%s: Error: isr = 0x%08X\n", __func__, 170a0735a34SSiva Durga Prasad Paladugu isr_status); 171a0735a34SSiva Durga Prasad Paladugu debug("%s: Write count = 0x%08X\n", __func__, 172a0735a34SSiva Durga Prasad Paladugu readl(&devcfg_base->write_count)); 173a0735a34SSiva Durga Prasad Paladugu debug("%s: Read count = 0x%08X\n", __func__, 174a0735a34SSiva Durga Prasad Paladugu readl(&devcfg_base->read_count)); 175a0735a34SSiva Durga Prasad Paladugu 176d5dae85fSMichal Simek return FPGA_FAIL; 177d5dae85fSMichal Simek } 178a0735a34SSiva Durga Prasad Paladugu if (get_timer(ts) > CONFIG_SYS_FPGA_PROG_TIME) { 179a0735a34SSiva Durga Prasad Paladugu printf("%s: Timeout wait for DMA to complete\n", 180c83a35f6SNovasys Ingenierie __func__); 181a0735a34SSiva Durga Prasad Paladugu return FPGA_FAIL; 182a0735a34SSiva Durga Prasad Paladugu } 183a0735a34SSiva Durga Prasad Paladugu isr_status = readl(&devcfg_base->int_sts); 184c83a35f6SNovasys Ingenierie } 185c83a35f6SNovasys Ingenierie 186a0735a34SSiva Durga Prasad Paladugu debug("%s: DMA transfer is done\n", __func__); 187d5dae85fSMichal Simek 188a0735a34SSiva Durga Prasad Paladugu /* Clear out the DMA status */ 189a0735a34SSiva Durga Prasad Paladugu writel(DEVCFG_ISR_DMA_DONE, &devcfg_base->int_sts); 190d5dae85fSMichal Simek 191a0735a34SSiva Durga Prasad Paladugu return FPGA_SUCCESS; 192d5dae85fSMichal Simek } 193d5dae85fSMichal Simek 1945b815c9cSMichal Simek static int zynq_dma_xfer_init(bitstream_type bstype) 195a0735a34SSiva Durga Prasad Paladugu { 196a0735a34SSiva Durga Prasad Paladugu u32 status, control, isr_status; 197a0735a34SSiva Durga Prasad Paladugu unsigned long ts; 198a0735a34SSiva Durga Prasad Paladugu 1995f93227cSSoren Brinkmann /* Clear loopback bit */ 2005f93227cSSoren Brinkmann clrbits_le32(&devcfg_base->mctrl, DEVCFG_MCTRL_PCAP_LPBK); 2015f93227cSSoren Brinkmann 2025b815c9cSMichal Simek if (bstype != BIT_PARTIAL) { 203d5dae85fSMichal Simek zynq_slcr_devcfg_disable(); 204d5dae85fSMichal Simek 205d5dae85fSMichal Simek /* Setting PCFG_PROG_B signal to high */ 206d5dae85fSMichal Simek control = readl(&devcfg_base->ctrl); 207d5dae85fSMichal Simek writel(control | DEVCFG_CTRL_PCFG_PROG_B, &devcfg_base->ctrl); 20871723aaeSSiva Durga Prasad Paladugu 20971723aaeSSiva Durga Prasad Paladugu /* 21071723aaeSSiva Durga Prasad Paladugu * Delay is required if AES efuse is selected as 21171723aaeSSiva Durga Prasad Paladugu * key source. 21271723aaeSSiva Durga Prasad Paladugu */ 21371723aaeSSiva Durga Prasad Paladugu if (control & DEVCFG_CTRL_PCFG_AES_EFUSE_MASK) 21471723aaeSSiva Durga Prasad Paladugu mdelay(5); 21571723aaeSSiva Durga Prasad Paladugu 216d5dae85fSMichal Simek /* Setting PCFG_PROG_B signal to low */ 217d5dae85fSMichal Simek writel(control & ~DEVCFG_CTRL_PCFG_PROG_B, &devcfg_base->ctrl); 218d5dae85fSMichal Simek 21971723aaeSSiva Durga Prasad Paladugu /* 22071723aaeSSiva Durga Prasad Paladugu * Delay is required if AES efuse is selected as 22171723aaeSSiva Durga Prasad Paladugu * key source. 22271723aaeSSiva Durga Prasad Paladugu */ 22371723aaeSSiva Durga Prasad Paladugu if (control & DEVCFG_CTRL_PCFG_AES_EFUSE_MASK) 22471723aaeSSiva Durga Prasad Paladugu mdelay(5); 22571723aaeSSiva Durga Prasad Paladugu 226d5dae85fSMichal Simek /* Polling the PCAP_INIT status for Reset */ 227d5dae85fSMichal Simek ts = get_timer(0); 228d5dae85fSMichal Simek while (readl(&devcfg_base->status) & DEVCFG_STATUS_PCFG_INIT) { 229d5dae85fSMichal Simek if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) { 230d5dae85fSMichal Simek printf("%s: Timeout wait for INIT to clear\n", 231d5dae85fSMichal Simek __func__); 232d5dae85fSMichal Simek return FPGA_FAIL; 233d5dae85fSMichal Simek } 234d5dae85fSMichal Simek } 235d5dae85fSMichal Simek 236d5dae85fSMichal Simek /* Setting PCFG_PROG_B signal to high */ 237d5dae85fSMichal Simek writel(control | DEVCFG_CTRL_PCFG_PROG_B, &devcfg_base->ctrl); 238d5dae85fSMichal Simek 239d5dae85fSMichal Simek /* Polling the PCAP_INIT status for Set */ 240d5dae85fSMichal Simek ts = get_timer(0); 241d5dae85fSMichal Simek while (!(readl(&devcfg_base->status) & 242d5dae85fSMichal Simek DEVCFG_STATUS_PCFG_INIT)) { 243d5dae85fSMichal Simek if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) { 244d5dae85fSMichal Simek printf("%s: Timeout wait for INIT to set\n", 245d5dae85fSMichal Simek __func__); 246d5dae85fSMichal Simek return FPGA_FAIL; 247d5dae85fSMichal Simek } 248d5dae85fSMichal Simek } 249d5dae85fSMichal Simek } 250d5dae85fSMichal Simek 251d5dae85fSMichal Simek isr_status = readl(&devcfg_base->int_sts); 252d5dae85fSMichal Simek 253d5dae85fSMichal Simek /* Clear it all, so if Boot ROM comes back, it can proceed */ 254d5dae85fSMichal Simek writel(0xFFFFFFFF, &devcfg_base->int_sts); 255d5dae85fSMichal Simek 256d5dae85fSMichal Simek if (isr_status & DEVCFG_ISR_FATAL_ERROR_MASK) { 257d5dae85fSMichal Simek debug("%s: Fatal errors in PCAP 0x%X\n", __func__, isr_status); 258d5dae85fSMichal Simek 259d5dae85fSMichal Simek /* If RX FIFO overflow, need to flush RX FIFO first */ 260d5dae85fSMichal Simek if (isr_status & DEVCFG_ISR_RX_FIFO_OV) { 261d5dae85fSMichal Simek writel(DEVCFG_MCTRL_RFIFO_FLUSH, &devcfg_base->mctrl); 262d5dae85fSMichal Simek writel(0xFFFFFFFF, &devcfg_base->int_sts); 263d5dae85fSMichal Simek } 264d5dae85fSMichal Simek return FPGA_FAIL; 265d5dae85fSMichal Simek } 266d5dae85fSMichal Simek 267d5dae85fSMichal Simek status = readl(&devcfg_base->status); 268d5dae85fSMichal Simek 269d5dae85fSMichal Simek debug("%s: Status = 0x%08X\n", __func__, status); 270d5dae85fSMichal Simek 271d5dae85fSMichal Simek if (status & DEVCFG_STATUS_DMA_CMD_Q_F) { 272d5dae85fSMichal Simek debug("%s: Error: device busy\n", __func__); 273d5dae85fSMichal Simek return FPGA_FAIL; 274d5dae85fSMichal Simek } 275d5dae85fSMichal Simek 276d5dae85fSMichal Simek debug("%s: Device ready\n", __func__); 277d5dae85fSMichal Simek 278d5dae85fSMichal Simek if (!(status & DEVCFG_STATUS_DMA_CMD_Q_E)) { 279d5dae85fSMichal Simek if (!(readl(&devcfg_base->int_sts) & DEVCFG_ISR_DMA_DONE)) { 280d5dae85fSMichal Simek /* Error state, transfer cannot occur */ 281d5dae85fSMichal Simek debug("%s: ISR indicates error\n", __func__); 282d5dae85fSMichal Simek return FPGA_FAIL; 283d5dae85fSMichal Simek } else { 284d5dae85fSMichal Simek /* Clear out the status */ 285d5dae85fSMichal Simek writel(DEVCFG_ISR_DMA_DONE, &devcfg_base->int_sts); 286d5dae85fSMichal Simek } 287d5dae85fSMichal Simek } 288d5dae85fSMichal Simek 289d5dae85fSMichal Simek if (status & DEVCFG_STATUS_DMA_DONE_CNT_MASK) { 290d5dae85fSMichal Simek /* Clear the count of completed DMA transfers */ 291d5dae85fSMichal Simek writel(DEVCFG_STATUS_DMA_DONE_CNT_MASK, &devcfg_base->status); 292d5dae85fSMichal Simek } 293d5dae85fSMichal Simek 294a0735a34SSiva Durga Prasad Paladugu return FPGA_SUCCESS; 295a0735a34SSiva Durga Prasad Paladugu } 296a0735a34SSiva Durga Prasad Paladugu 297a0735a34SSiva Durga Prasad Paladugu static u32 *zynq_align_dma_buffer(u32 *buf, u32 len, u32 swap) 298a0735a34SSiva Durga Prasad Paladugu { 299a0735a34SSiva Durga Prasad Paladugu u32 *new_buf; 300a0735a34SSiva Durga Prasad Paladugu u32 i; 301a0735a34SSiva Durga Prasad Paladugu 302a0735a34SSiva Durga Prasad Paladugu if ((u32)buf != ALIGN((u32)buf, ARCH_DMA_MINALIGN)) { 303a0735a34SSiva Durga Prasad Paladugu new_buf = (u32 *)ALIGN((u32)buf, ARCH_DMA_MINALIGN); 304a0735a34SSiva Durga Prasad Paladugu 305a0735a34SSiva Durga Prasad Paladugu /* 306a0735a34SSiva Durga Prasad Paladugu * This might be dangerous but permits to flash if 307a0735a34SSiva Durga Prasad Paladugu * ARCH_DMA_MINALIGN is greater than header size 308a0735a34SSiva Durga Prasad Paladugu */ 309a0735a34SSiva Durga Prasad Paladugu if (new_buf > buf) { 310a0735a34SSiva Durga Prasad Paladugu debug("%s: Aligned buffer is after buffer start\n", 311a0735a34SSiva Durga Prasad Paladugu __func__); 312a0735a34SSiva Durga Prasad Paladugu new_buf -= ARCH_DMA_MINALIGN; 313a0735a34SSiva Durga Prasad Paladugu } 314a0735a34SSiva Durga Prasad Paladugu printf("%s: Align buffer at %x to %x(swap %d)\n", __func__, 315a0735a34SSiva Durga Prasad Paladugu (u32)buf, (u32)new_buf, swap); 316a0735a34SSiva Durga Prasad Paladugu 317a0735a34SSiva Durga Prasad Paladugu for (i = 0; i < (len/4); i++) 318a0735a34SSiva Durga Prasad Paladugu new_buf[i] = load_word(&buf[i], swap); 319a0735a34SSiva Durga Prasad Paladugu 320a0735a34SSiva Durga Prasad Paladugu buf = new_buf; 321a0735a34SSiva Durga Prasad Paladugu } else if (swap != SWAP_DONE) { 322a0735a34SSiva Durga Prasad Paladugu /* For bitstream which are aligned */ 323a0735a34SSiva Durga Prasad Paladugu u32 *new_buf = (u32 *)buf; 324a0735a34SSiva Durga Prasad Paladugu 325a0735a34SSiva Durga Prasad Paladugu printf("%s: Bitstream is not swapped(%d) - swap it\n", __func__, 326a0735a34SSiva Durga Prasad Paladugu swap); 327a0735a34SSiva Durga Prasad Paladugu 328a0735a34SSiva Durga Prasad Paladugu for (i = 0; i < (len/4); i++) 329a0735a34SSiva Durga Prasad Paladugu new_buf[i] = load_word(&buf[i], swap); 330a0735a34SSiva Durga Prasad Paladugu } 331a0735a34SSiva Durga Prasad Paladugu 332a0735a34SSiva Durga Prasad Paladugu return buf; 333a0735a34SSiva Durga Prasad Paladugu } 334a0735a34SSiva Durga Prasad Paladugu 33531081859SSiva Durga Prasad Paladugu static int zynq_validate_bitstream(xilinx_desc *desc, const void *buf, 33631081859SSiva Durga Prasad Paladugu size_t bsize, u32 blocksize, u32 *swap, 3375b815c9cSMichal Simek bitstream_type *bstype) 338a0735a34SSiva Durga Prasad Paladugu { 339a0735a34SSiva Durga Prasad Paladugu u32 *buf_start; 34031081859SSiva Durga Prasad Paladugu u32 diff; 341a0735a34SSiva Durga Prasad Paladugu 34231081859SSiva Durga Prasad Paladugu buf_start = check_data((u8 *)buf, blocksize, swap); 343a0735a34SSiva Durga Prasad Paladugu 344a0735a34SSiva Durga Prasad Paladugu if (!buf_start) 345a0735a34SSiva Durga Prasad Paladugu return FPGA_FAIL; 346a0735a34SSiva Durga Prasad Paladugu 347a0735a34SSiva Durga Prasad Paladugu /* Check if data is postpone from start */ 348a0735a34SSiva Durga Prasad Paladugu diff = (u32)buf_start - (u32)buf; 349a0735a34SSiva Durga Prasad Paladugu if (diff) { 350a0735a34SSiva Durga Prasad Paladugu printf("%s: Bitstream is not validated yet (diff %x)\n", 351a0735a34SSiva Durga Prasad Paladugu __func__, diff); 352a0735a34SSiva Durga Prasad Paladugu return FPGA_FAIL; 353a0735a34SSiva Durga Prasad Paladugu } 354a0735a34SSiva Durga Prasad Paladugu 355a0735a34SSiva Durga Prasad Paladugu if ((u32)buf < SZ_1M) { 356a0735a34SSiva Durga Prasad Paladugu printf("%s: Bitstream has to be placed up to 1MB (%x)\n", 357a0735a34SSiva Durga Prasad Paladugu __func__, (u32)buf); 358a0735a34SSiva Durga Prasad Paladugu return FPGA_FAIL; 359a0735a34SSiva Durga Prasad Paladugu } 360a0735a34SSiva Durga Prasad Paladugu 3615b815c9cSMichal Simek if (zynq_dma_xfer_init(*bstype)) 36231081859SSiva Durga Prasad Paladugu return FPGA_FAIL; 36331081859SSiva Durga Prasad Paladugu 36431081859SSiva Durga Prasad Paladugu return 0; 36531081859SSiva Durga Prasad Paladugu } 36631081859SSiva Durga Prasad Paladugu 3677a78bd26SMichal Simek static int zynq_load(xilinx_desc *desc, const void *buf, size_t bsize, 3687a78bd26SMichal Simek bitstream_type bstype) 36931081859SSiva Durga Prasad Paladugu { 37031081859SSiva Durga Prasad Paladugu unsigned long ts; /* Timestamp */ 37131081859SSiva Durga Prasad Paladugu u32 isr_status, swap; 37231081859SSiva Durga Prasad Paladugu 37331081859SSiva Durga Prasad Paladugu /* 37431081859SSiva Durga Prasad Paladugu * send bsize inplace of blocksize as it was not a bitstream 37531081859SSiva Durga Prasad Paladugu * in chunks 37631081859SSiva Durga Prasad Paladugu */ 37731081859SSiva Durga Prasad Paladugu if (zynq_validate_bitstream(desc, buf, bsize, bsize, &swap, 3785b815c9cSMichal Simek &bstype)) 379a0735a34SSiva Durga Prasad Paladugu return FPGA_FAIL; 380a0735a34SSiva Durga Prasad Paladugu 381a0735a34SSiva Durga Prasad Paladugu buf = zynq_align_dma_buffer((u32 *)buf, bsize, swap); 382a0735a34SSiva Durga Prasad Paladugu 383d5dae85fSMichal Simek debug("%s: Source = 0x%08X\n", __func__, (u32)buf); 384d5dae85fSMichal Simek debug("%s: Size = %zu\n", __func__, bsize); 385d5dae85fSMichal Simek 386ec4b73f0SJagannadha Sutradharudu Teki /* flush(clean & invalidate) d-cache range buf */ 387ec4b73f0SJagannadha Sutradharudu Teki flush_dcache_range((u32)buf, (u32)buf + 388ec4b73f0SJagannadha Sutradharudu Teki roundup(bsize, ARCH_DMA_MINALIGN)); 389ec4b73f0SJagannadha Sutradharudu Teki 390a0735a34SSiva Durga Prasad Paladugu if (zynq_dma_transfer((u32)buf | 1, bsize >> 2, 0xffffffff, 0)) 391a0735a34SSiva Durga Prasad Paladugu return FPGA_FAIL; 392d5dae85fSMichal Simek 393d5dae85fSMichal Simek isr_status = readl(&devcfg_base->int_sts); 394d5dae85fSMichal Simek /* Check FPGA configuration completion */ 395d5dae85fSMichal Simek ts = get_timer(0); 396d5dae85fSMichal Simek while (!(isr_status & DEVCFG_ISR_PCFG_DONE)) { 397d5dae85fSMichal Simek if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) { 398d5dae85fSMichal Simek printf("%s: Timeout wait for FPGA to config\n", 399d5dae85fSMichal Simek __func__); 400d5dae85fSMichal Simek return FPGA_FAIL; 401d5dae85fSMichal Simek } 402d5dae85fSMichal Simek isr_status = readl(&devcfg_base->int_sts); 403d5dae85fSMichal Simek } 404d5dae85fSMichal Simek 405d5dae85fSMichal Simek debug("%s: FPGA config done\n", __func__); 406d5dae85fSMichal Simek 4075b815c9cSMichal Simek if (bstype != BIT_PARTIAL) 408d5dae85fSMichal Simek zynq_slcr_devcfg_enable(); 409d5dae85fSMichal Simek 410d5dae85fSMichal Simek return FPGA_SUCCESS; 411d5dae85fSMichal Simek } 412d5dae85fSMichal Simek 4131a897668SSiva Durga Prasad Paladugu #if defined(CONFIG_CMD_FPGA_LOADFS) 4141a897668SSiva Durga Prasad Paladugu static int zynq_loadfs(xilinx_desc *desc, const void *buf, size_t bsize, 4151a897668SSiva Durga Prasad Paladugu fpga_fs_info *fsinfo) 4161a897668SSiva Durga Prasad Paladugu { 4171a897668SSiva Durga Prasad Paladugu unsigned long ts; /* Timestamp */ 4181a897668SSiva Durga Prasad Paladugu u32 isr_status, swap; 4191a897668SSiva Durga Prasad Paladugu u32 partialbit = 0; 420d455d878SSuriyan Ramasami loff_t blocksize, actread; 421d455d878SSuriyan Ramasami loff_t pos = 0; 4221a897668SSiva Durga Prasad Paladugu int fstype; 4231a897668SSiva Durga Prasad Paladugu char *interface, *dev_part, *filename; 4241a897668SSiva Durga Prasad Paladugu 4251a897668SSiva Durga Prasad Paladugu blocksize = fsinfo->blocksize; 4261a897668SSiva Durga Prasad Paladugu interface = fsinfo->interface; 4271a897668SSiva Durga Prasad Paladugu dev_part = fsinfo->dev_part; 4281a897668SSiva Durga Prasad Paladugu filename = fsinfo->filename; 4291a897668SSiva Durga Prasad Paladugu fstype = fsinfo->fstype; 4301a897668SSiva Durga Prasad Paladugu 4311a897668SSiva Durga Prasad Paladugu if (fs_set_blk_dev(interface, dev_part, fstype)) 4321a897668SSiva Durga Prasad Paladugu return FPGA_FAIL; 4331a897668SSiva Durga Prasad Paladugu 434d455d878SSuriyan Ramasami if (fs_read(filename, (u32) buf, pos, blocksize, &actread) < 0) 4351a897668SSiva Durga Prasad Paladugu return FPGA_FAIL; 4361a897668SSiva Durga Prasad Paladugu 4371a897668SSiva Durga Prasad Paladugu if (zynq_validate_bitstream(desc, buf, bsize, blocksize, &swap, 4381a897668SSiva Durga Prasad Paladugu &partialbit)) 4391a897668SSiva Durga Prasad Paladugu return FPGA_FAIL; 4401a897668SSiva Durga Prasad Paladugu 4411a897668SSiva Durga Prasad Paladugu dcache_disable(); 4421a897668SSiva Durga Prasad Paladugu 4431a897668SSiva Durga Prasad Paladugu do { 4441a897668SSiva Durga Prasad Paladugu buf = zynq_align_dma_buffer((u32 *)buf, blocksize, swap); 4451a897668SSiva Durga Prasad Paladugu 4461a897668SSiva Durga Prasad Paladugu if (zynq_dma_transfer((u32)buf | 1, blocksize >> 2, 4471a897668SSiva Durga Prasad Paladugu 0xffffffff, 0)) 4481a897668SSiva Durga Prasad Paladugu return FPGA_FAIL; 4491a897668SSiva Durga Prasad Paladugu 4501a897668SSiva Durga Prasad Paladugu bsize -= blocksize; 4511a897668SSiva Durga Prasad Paladugu pos += blocksize; 4521a897668SSiva Durga Prasad Paladugu 4531a897668SSiva Durga Prasad Paladugu if (fs_set_blk_dev(interface, dev_part, fstype)) 4541a897668SSiva Durga Prasad Paladugu return FPGA_FAIL; 4551a897668SSiva Durga Prasad Paladugu 4561a897668SSiva Durga Prasad Paladugu if (bsize > blocksize) { 457d455d878SSuriyan Ramasami if (fs_read(filename, (u32) buf, pos, blocksize, &actread) < 0) 4581a897668SSiva Durga Prasad Paladugu return FPGA_FAIL; 4591a897668SSiva Durga Prasad Paladugu } else { 460d455d878SSuriyan Ramasami if (fs_read(filename, (u32) buf, pos, bsize, &actread) < 0) 4611a897668SSiva Durga Prasad Paladugu return FPGA_FAIL; 4621a897668SSiva Durga Prasad Paladugu } 4631a897668SSiva Durga Prasad Paladugu } while (bsize > blocksize); 4641a897668SSiva Durga Prasad Paladugu 4651a897668SSiva Durga Prasad Paladugu buf = zynq_align_dma_buffer((u32 *)buf, blocksize, swap); 4661a897668SSiva Durga Prasad Paladugu 4671a897668SSiva Durga Prasad Paladugu if (zynq_dma_transfer((u32)buf | 1, bsize >> 2, 0xffffffff, 0)) 4681a897668SSiva Durga Prasad Paladugu return FPGA_FAIL; 4691a897668SSiva Durga Prasad Paladugu 4701a897668SSiva Durga Prasad Paladugu dcache_enable(); 4711a897668SSiva Durga Prasad Paladugu 4721a897668SSiva Durga Prasad Paladugu isr_status = readl(&devcfg_base->int_sts); 4731a897668SSiva Durga Prasad Paladugu 4741a897668SSiva Durga Prasad Paladugu /* Check FPGA configuration completion */ 4751a897668SSiva Durga Prasad Paladugu ts = get_timer(0); 4761a897668SSiva Durga Prasad Paladugu while (!(isr_status & DEVCFG_ISR_PCFG_DONE)) { 4771a897668SSiva Durga Prasad Paladugu if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) { 4781a897668SSiva Durga Prasad Paladugu printf("%s: Timeout wait for FPGA to config\n", 4791a897668SSiva Durga Prasad Paladugu __func__); 4801a897668SSiva Durga Prasad Paladugu return FPGA_FAIL; 4811a897668SSiva Durga Prasad Paladugu } 4821a897668SSiva Durga Prasad Paladugu isr_status = readl(&devcfg_base->int_sts); 4831a897668SSiva Durga Prasad Paladugu } 4841a897668SSiva Durga Prasad Paladugu 4851a897668SSiva Durga Prasad Paladugu debug("%s: FPGA config done\n", __func__); 4861a897668SSiva Durga Prasad Paladugu 4871a897668SSiva Durga Prasad Paladugu if (!partialbit) 4881a897668SSiva Durga Prasad Paladugu zynq_slcr_devcfg_enable(); 4891a897668SSiva Durga Prasad Paladugu 4901a897668SSiva Durga Prasad Paladugu return FPGA_SUCCESS; 4911a897668SSiva Durga Prasad Paladugu } 4921a897668SSiva Durga Prasad Paladugu #endif 4931a897668SSiva Durga Prasad Paladugu 49414cfc4f3SMichal Simek struct xilinx_fpga_op zynq_op = { 49514cfc4f3SMichal Simek .load = zynq_load, 4961a897668SSiva Durga Prasad Paladugu #if defined(CONFIG_CMD_FPGA_LOADFS) 4971a897668SSiva Durga Prasad Paladugu .loadfs = zynq_loadfs, 4981a897668SSiva Durga Prasad Paladugu #endif 49914cfc4f3SMichal Simek }; 500