1c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 2c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * (C) Copyright 2002 3c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Rich Ireland, Enterasys Networks, rireland@enterasys.com. 4c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Keith Outwater, keith_outwater@mvis.com 5c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * 61a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 7c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 8c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 9c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 10c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Configuration support for Xilinx Virtex2 devices. Based 11c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * on spartan2.c (Rich Ireland, rireland@enterasys.com). 12c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 13c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 14c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #include <common.h> 15c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #include <virtex2.h> 16c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 17c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #if 0 18c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define FPGA_DEBUG 19c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 20c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 21c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef FPGA_DEBUG 22c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define PRINTF(fmt,args...) printf (fmt ,##args) 23c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #else 24c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define PRINTF(fmt,args...) 25c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 26c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 27c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 28c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * If the SelectMap interface can be overrun by the processor, define 29c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * CONFIG_SYS_FPGA_CHECK_BUSY and/or CONFIG_FPGA_DELAY in the board configuration 30c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * file and add board-specific support for checking BUSY status. By default, 31c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * assume that the SelectMap interface cannot be overrun. 32c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 33c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_FPGA_CHECK_BUSY 34c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #undef CONFIG_SYS_FPGA_CHECK_BUSY 35c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 36c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 37c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_FPGA_DELAY 38c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_FPGA_DELAY() 39c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 40c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 41c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_FPGA_PROG_FEEDBACK 42c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_SYS_FPGA_PROG_FEEDBACK 43c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 44c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 45c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 46c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Don't allow config cycle to be interrupted 47c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 48c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_FPGA_CHECK_CTRLC 49c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #undef CONFIG_SYS_FPGA_CHECK_CTRLC 50c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 51c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 52c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 53c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Check for errors during configuration by default 54c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 55c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_FPGA_CHECK_ERROR 56c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_SYS_FPGA_CHECK_ERROR 57c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 58c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 59c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 60c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * The default timeout in mS for INIT_B to deassert after PROG_B has 61c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * been deasserted. Per the latest Virtex II Handbook (page 347), the 62c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * max time from PORG_B deassertion to INIT_B deassertion is 4uS per 63c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * data frame for the XC2V8000. The XC2V8000 has 2860 data frames 64c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * which yields 11.44 mS. So let's make it bigger in order to handle 65c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * an XC2V1000, if anyone can ever get ahold of one. 66c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 67c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_FPGA_WAIT_INIT 68c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_SYS_FPGA_WAIT_INIT CONFIG_SYS_HZ/2 /* 500 ms */ 69c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 70c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 71c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 72c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * The default timeout for waiting for BUSY to deassert during configuration. 73c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * This is normally not necessary since for most reasonable configuration 74c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * clock frequencies (i.e. 66 MHz or less), BUSY monitoring is unnecessary. 75c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 76c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_FPGA_WAIT_BUSY 77c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_SYS_FPGA_WAIT_BUSY CONFIG_SYS_HZ/200 /* 5 ms*/ 78c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 79c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 80c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Default timeout for waiting for FPGA to enter operational mode after 81c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * configuration data has been written. 82c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 83c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_FPGA_WAIT_CONFIG 84c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_SYS_FPGA_WAIT_CONFIG CONFIG_SYS_HZ/5 /* 200 ms */ 85c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 86c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 87f8c1be98SMichal Simek static int virtex2_ssm_load(xilinx_desc *desc, const void *buf, size_t bsize); 88f8c1be98SMichal Simek static int virtex2_ssm_dump(xilinx_desc *desc, const void *buf, size_t bsize); 89c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 90f8c1be98SMichal Simek static int virtex2_ss_load(xilinx_desc *desc, const void *buf, size_t bsize); 91f8c1be98SMichal Simek static int virtex2_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize); 92c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 93*7a78bd26SMichal Simek static int virtex2_load(xilinx_desc *desc, const void *buf, size_t bsize, 94*7a78bd26SMichal Simek bitstream_type bstype) 95c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD { 96c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int ret_val = FPGA_FAIL; 97c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 98c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD switch (desc->iface) { 99c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD case slave_serial: 100c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__); 101d9071ce0SMichal Simek ret_val = virtex2_ss_load(desc, buf, bsize); 102c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD break; 103c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 104c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD case slave_selectmap: 105c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__); 106d9071ce0SMichal Simek ret_val = virtex2_ssm_load(desc, buf, bsize); 107c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD break; 108c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 109c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD default: 110c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s: Unsupported interface type, %d\n", 111c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, desc->iface); 112c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 113c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return ret_val; 114c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 115c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 11614cfc4f3SMichal Simek static int virtex2_dump(xilinx_desc *desc, const void *buf, size_t bsize) 117c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD { 118c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int ret_val = FPGA_FAIL; 119c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 120c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD switch (desc->iface) { 121c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD case slave_serial: 122c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__); 123d9071ce0SMichal Simek ret_val = virtex2_ss_dump(desc, buf, bsize); 124c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD break; 125c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 126c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD case slave_parallel: 127c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__); 128d9071ce0SMichal Simek ret_val = virtex2_ssm_dump(desc, buf, bsize); 129c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD break; 130c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 131c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD default: 132c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s: Unsupported interface type, %d\n", 133c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, desc->iface); 134c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 135c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return ret_val; 136c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 137c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 13814cfc4f3SMichal Simek static int virtex2_info(xilinx_desc *desc) 139c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD { 140c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_SUCCESS; 141c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 142c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 143c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 144c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Virtex-II Slave SelectMap configuration loader. Configuration via 145c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * SelectMap is as follows: 146c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * 1. Set the FPGA's PROG_B line low. 147c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * 2. Set the FPGA's PROG_B line high. Wait for INIT_B to go high. 148c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * 3. Write data to the SelectMap port. If INIT_B goes low at any time 149c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * this process, a configuration error (most likely CRC failure) has 150c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * ocurred. At this point a status word may be read from the 151c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * SelectMap interface to determine the source of the problem (You 152c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * could, for instance, put this in your 'abort' function handler). 153c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * 4. After all data has been written, test the state of the FPGA 154c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * INIT_B and DONE lines. If both are high, configuration has 155c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * succeeded. Congratulations! 156c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 157f8c1be98SMichal Simek static int virtex2_ssm_load(xilinx_desc *desc, const void *buf, size_t bsize) 158c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD { 159c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int ret_val = FPGA_FAIL; 160d9071ce0SMichal Simek xilinx_virtex2_slave_selectmap_fns *fn = desc->iface_fns; 161c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 162c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF ("%s:%d: Start with interface functions @ 0x%p\n", 163c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, __LINE__, fn); 164c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 165c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (fn) { 166c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD size_t bytecount = 0; 167c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD unsigned char *data = (unsigned char *) buf; 168c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int cookie = desc->cookie; 169c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD unsigned long ts; 170c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 171c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Gotta split this one up (so the stack won't blow??) */ 172c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF ("%s:%d: Function Table:\n" 173c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " base 0x%p\n" 174c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " struct 0x%p\n" 175c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " pre 0x%p\n" 176c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " prog 0x%p\n" 177c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " init 0x%p\n" 178c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " error 0x%p\n", 179c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, __LINE__, 180c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD &fn, fn, fn->pre, fn->pgm, fn->init, fn->err); 181c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF (" clock 0x%p\n" 182c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " cs 0x%p\n" 183c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " write 0x%p\n" 184c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " rdata 0x%p\n" 185c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " wdata 0x%p\n" 186c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " busy 0x%p\n" 187c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " abort 0x%p\n" 188c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " post 0x%p\n\n", 189c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, 190c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD fn->busy, fn->abort, fn->post); 191c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 192c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK 193c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("Initializing FPGA Device %d...\n", cookie); 194c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 195c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 196c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Run the pre configuration function if there is one. 197c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 198c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (*fn->pre) { 199c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->pre) (cookie); 200c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 201c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 202c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 203c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Assert the program line. The minimum pulse width for 204c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Virtex II devices is 300 nS (Tprogram parameter in datasheet). 205c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * There is no maximum value for the pulse width. Check to make 206c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * sure that INIT_B goes low after assertion of PROG_B 207c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 208472d5460SYork Sun (*fn->pgm) (true, true, cookie); 209c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD udelay (10); 210c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ts = get_timer (0); 211c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD do { 212c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_INIT) { 213c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s:%d: ** Timeout after %d ticks waiting for INIT" 214c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " to assert.\n", __FUNCTION__, __LINE__, 215c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_SYS_FPGA_WAIT_INIT); 216c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->abort) (cookie); 217c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_FAIL; 218c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 219c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } while (!(*fn->init) (cookie)); 220c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 221472d5460SYork Sun (*fn->pgm) (false, true, cookie); 222c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY (); 223472d5460SYork Sun (*fn->clk) (true, true, cookie); 224c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 225c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 226c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Start a timer and wait for INIT_B to go high 227c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 228c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ts = get_timer (0); 229c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD do { 230c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY (); 231c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_INIT) { 232c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s:%d: ** Timeout after %d ticks waiting for INIT" 233c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " to deassert.\n", __FUNCTION__, __LINE__, 234c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_SYS_FPGA_WAIT_INIT); 235c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->abort) (cookie); 236c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_FAIL; 237c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 238c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } while ((*fn->init) (cookie) && (*fn->busy) (cookie)); 239c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 240472d5460SYork Sun (*fn->wr) (true, true, cookie); 241472d5460SYork Sun (*fn->cs) (true, true, cookie); 242c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 243c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD udelay (10000); 244c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 245c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 246c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Load the data byte by byte 247c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 248c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD while (bytecount < bsize) { 249c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_CHECK_CTRLC 250c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (ctrlc ()) { 251c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->abort) (cookie); 252c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_FAIL; 253c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 254c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 255c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 256c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if ((*fn->done) (cookie) == FPGA_SUCCESS) { 257c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF ("%s:%d:done went active early, bytecount = %d\n", 258c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, __LINE__, bytecount); 259c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD break; 260c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 261c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 262c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_CHECK_ERROR 263c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if ((*fn->init) (cookie)) { 264c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("\n%s:%d: ** Error: INIT asserted during" 265c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " configuration\n", __FUNCTION__, __LINE__); 266c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%d = buffer offset, %d = buffer size\n", 267c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD bytecount, bsize); 268c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->abort) (cookie); 269c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_FAIL; 270c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 271c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 272c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 273472d5460SYork Sun (*fn->wdata) (data[bytecount++], true, cookie); 274c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY (); 275c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 276c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 277c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Cycle the clock pin 278c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 279472d5460SYork Sun (*fn->clk) (false, true, cookie); 280c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY (); 281472d5460SYork Sun (*fn->clk) (true, true, cookie); 282c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 283c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_CHECK_BUSY 284c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ts = get_timer (0); 285c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD while ((*fn->busy) (cookie)) { 286c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_BUSY) { 287c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s:%d: ** Timeout after %d ticks waiting for" 288c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " BUSY to deassert\n", 289c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, __LINE__, CONFIG_SYS_FPGA_WAIT_BUSY); 290c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->abort) (cookie); 291c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_FAIL; 292c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 293c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 294c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 295c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 296c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK 297c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (bytecount % (bsize / 40) == 0) 298c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD putc ('.'); 299c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 300c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 301c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 302c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 303c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Finished writing the data; deassert FPGA CS_B and WRITE_B signals. 304c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 305c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY (); 306472d5460SYork Sun (*fn->cs) (false, true, cookie); 307472d5460SYork Sun (*fn->wr) (false, true, cookie); 308c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 309c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK 310c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD putc ('\n'); 311c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 312c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 313c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 314c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Check for successful configuration. FPGA INIT_B and DONE should 315c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * both be high upon successful configuration. 316c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 317c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ts = get_timer (0); 318c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ret_val = FPGA_SUCCESS; 319c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD while (((*fn->done) (cookie) == FPGA_FAIL) || (*fn->init) (cookie)) { 320c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_CONFIG) { 321c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s:%d: ** Timeout after %d ticks waiting for DONE to" 322c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD "assert and INIT to deassert\n", 323c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, __LINE__, CONFIG_SYS_FPGA_WAIT_CONFIG); 324c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->abort) (cookie); 325c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ret_val = FPGA_FAIL; 326c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD break; 327c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 328c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 329c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 330c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (ret_val == FPGA_SUCCESS) { 331c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK 332c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("Initialization of FPGA device %d complete\n", cookie); 333c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 334c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 335c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Run the post configuration function if there is one. 336c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 337c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (*fn->post) { 338c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->post) (cookie); 339c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 340c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } else { 341c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK 342c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("** Initialization of FPGA device %d FAILED\n", 343c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD cookie); 344c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 345c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 346c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } else { 347c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s:%d: NULL Interface function table!\n", 348c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, __LINE__); 349c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 350c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return ret_val; 351c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 352c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 353c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 354c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Read the FPGA configuration data 355c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 356f8c1be98SMichal Simek static int virtex2_ssm_dump(xilinx_desc *desc, const void *buf, size_t bsize) 357c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD { 358c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int ret_val = FPGA_FAIL; 359d9071ce0SMichal Simek xilinx_virtex2_slave_selectmap_fns *fn = desc->iface_fns; 360c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 361c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (fn) { 362c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD unsigned char *data = (unsigned char *) buf; 363c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD size_t bytecount = 0; 364c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int cookie = desc->cookie; 365c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 366c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("Starting Dump of FPGA Device %d...\n", cookie); 367c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 368472d5460SYork Sun (*fn->cs) (true, true, cookie); 369472d5460SYork Sun (*fn->clk) (true, true, cookie); 370c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 371c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD while (bytecount < bsize) { 372c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_CHECK_CTRLC 373c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (ctrlc ()) { 374c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->abort) (cookie); 375c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_FAIL; 376c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 377c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 378c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 379c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Cycle the clock and read the data 380c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 381472d5460SYork Sun (*fn->clk) (false, true, cookie); 382472d5460SYork Sun (*fn->clk) (true, true, cookie); 383c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->rdata) (&(data[bytecount++]), cookie); 384c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK 385c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (bytecount % (bsize / 40) == 0) 386c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD putc ('.'); 387c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 388c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 389c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 390c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 391c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Deassert CS_B and cycle the clock to deselect the device. 392c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 393472d5460SYork Sun (*fn->cs) (false, false, cookie); 394472d5460SYork Sun (*fn->clk) (false, true, cookie); 395472d5460SYork Sun (*fn->clk) (true, true, cookie); 396c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 397c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK 398c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD putc ('\n'); 399c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 400c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD puts ("Done.\n"); 401c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } else { 402c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s:%d: NULL Interface function table!\n", 403c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, __LINE__); 404c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 405c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return ret_val; 406c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 407c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 408f8c1be98SMichal Simek static int virtex2_ss_load(xilinx_desc *desc, const void *buf, size_t bsize) 409c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD { 410c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s: Slave Serial Loading is unsupported\n", __FUNCTION__); 411c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_FAIL; 412c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 413c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 414f8c1be98SMichal Simek static int virtex2_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize) 415c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD { 416c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s: Slave Serial Dumping is unsupported\n", __FUNCTION__); 417c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_FAIL; 418c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 419c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 420c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* vim: set ts=4 tw=78: */ 42114cfc4f3SMichal Simek 42214cfc4f3SMichal Simek struct xilinx_fpga_op virtex2_op = { 42314cfc4f3SMichal Simek .load = virtex2_load, 42414cfc4f3SMichal Simek .dump = virtex2_dump, 42514cfc4f3SMichal Simek .info = virtex2_info, 42614cfc4f3SMichal Simek }; 427