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