1*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 2*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * (C) Copyright 2002 3*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Rich Ireland, Enterasys Networks, rireland@enterasys.com. 4*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Keith Outwater, keith_outwater@mvis.com 5*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * 6*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * See file CREDITS for list of people who contributed to this 7*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * project. 8*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * 9*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * This program is free software; you can redistribute it and/or 10*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * modify it under the terms of the GNU General Public License as 11*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * published by the Free Software Foundation; either version 2 of 12*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * the License, or (at your option) any later version. 13*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * 14*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * This program is distributed in the hope that it will be useful, 15*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * but WITHOUT ANY WARRANTY; without even the implied warranty of 16*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * GNU General Public License for more details. 18*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * 19*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * You should have received a copy of the GNU General Public License 20*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * along with this program; if not, write to the Free Software 21*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 22*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * MA 02111-1307 USA 23*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * 24*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 25*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 26*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 27*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Configuration support for Xilinx Virtex2 devices. Based 28*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * on spartan2.c (Rich Ireland, rireland@enterasys.com). 29*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 30*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 31*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #include <common.h> 32*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #include <virtex2.h> 33*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 34*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #if 0 35*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define FPGA_DEBUG 36*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 37*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 38*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef FPGA_DEBUG 39*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define PRINTF(fmt,args...) printf (fmt ,##args) 40*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #else 41*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define PRINTF(fmt,args...) 42*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 43*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 44*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 45*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * If the SelectMap interface can be overrun by the processor, define 46*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * CONFIG_SYS_FPGA_CHECK_BUSY and/or CONFIG_FPGA_DELAY in the board configuration 47*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * file and add board-specific support for checking BUSY status. By default, 48*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * assume that the SelectMap interface cannot be overrun. 49*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 50*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_FPGA_CHECK_BUSY 51*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #undef CONFIG_SYS_FPGA_CHECK_BUSY 52*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 53*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 54*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_FPGA_DELAY 55*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_FPGA_DELAY() 56*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 57*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 58*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_FPGA_PROG_FEEDBACK 59*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_SYS_FPGA_PROG_FEEDBACK 60*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 61*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 62*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 63*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Don't allow config cycle to be interrupted 64*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 65*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_FPGA_CHECK_CTRLC 66*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #undef CONFIG_SYS_FPGA_CHECK_CTRLC 67*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 68*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 69*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 70*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Check for errors during configuration by default 71*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 72*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_FPGA_CHECK_ERROR 73*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_SYS_FPGA_CHECK_ERROR 74*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 75*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 76*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 77*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * The default timeout in mS for INIT_B to deassert after PROG_B has 78*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * been deasserted. Per the latest Virtex II Handbook (page 347), the 79*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * max time from PORG_B deassertion to INIT_B deassertion is 4uS per 80*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * data frame for the XC2V8000. The XC2V8000 has 2860 data frames 81*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * which yields 11.44 mS. So let's make it bigger in order to handle 82*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * an XC2V1000, if anyone can ever get ahold of one. 83*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 84*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_FPGA_WAIT_INIT 85*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_SYS_FPGA_WAIT_INIT CONFIG_SYS_HZ/2 /* 500 ms */ 86*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 87*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 88*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 89*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * The default timeout for waiting for BUSY to deassert during configuration. 90*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * This is normally not necessary since for most reasonable configuration 91*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * clock frequencies (i.e. 66 MHz or less), BUSY monitoring is unnecessary. 92*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 93*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_FPGA_WAIT_BUSY 94*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_SYS_FPGA_WAIT_BUSY CONFIG_SYS_HZ/200 /* 5 ms*/ 95*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 96*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 97*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Default timeout for waiting for FPGA to enter operational mode after 98*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * configuration data has been written. 99*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 100*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_FPGA_WAIT_CONFIG 101*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_SYS_FPGA_WAIT_CONFIG CONFIG_SYS_HZ/5 /* 200 ms */ 102*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 103*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 104*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize); 105*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int Virtex2_ssm_dump (Xilinx_desc * desc, void *buf, size_t bsize); 106*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int Virtex2_ssm_reloc (Xilinx_desc * desc, ulong reloc_offset); 107*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 108*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int Virtex2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize); 109*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int Virtex2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize); 110*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int Virtex2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset); 111*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 112*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int Virtex2_load (Xilinx_desc * desc, void *buf, size_t bsize) 113*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD { 114*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int ret_val = FPGA_FAIL; 115*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 116*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD switch (desc->iface) { 117*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD case slave_serial: 118*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__); 119*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ret_val = Virtex2_ss_load (desc, buf, bsize); 120*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD break; 121*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 122*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD case slave_selectmap: 123*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__); 124*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ret_val = Virtex2_ssm_load (desc, buf, bsize); 125*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD break; 126*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 127*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD default: 128*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s: Unsupported interface type, %d\n", 129*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, desc->iface); 130*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 131*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return ret_val; 132*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 133*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 134*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int Virtex2_dump (Xilinx_desc * desc, void *buf, size_t bsize) 135*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD { 136*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int ret_val = FPGA_FAIL; 137*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 138*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD switch (desc->iface) { 139*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD case slave_serial: 140*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__); 141*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ret_val = Virtex2_ss_dump (desc, buf, bsize); 142*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD break; 143*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 144*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD case slave_parallel: 145*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__); 146*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ret_val = Virtex2_ssm_dump (desc, buf, bsize); 147*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD break; 148*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 149*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD default: 150*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s: Unsupported interface type, %d\n", 151*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, desc->iface); 152*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 153*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return ret_val; 154*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 155*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 156*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int Virtex2_info (Xilinx_desc * desc) 157*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD { 158*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_SUCCESS; 159*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 160*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 161*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int Virtex2_reloc (Xilinx_desc * desc, ulong reloc_offset) 162*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD { 163*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int ret_val = FPGA_FAIL; 164*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 165*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (desc->family != Xilinx_Virtex2) { 166*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s: Unsupported family type, %d\n", 167*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, desc->family); 168*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_FAIL; 169*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } else 170*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD switch (desc->iface) { 171*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD case slave_serial: 172*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ret_val = Virtex2_ss_reloc (desc, reloc_offset); 173*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD break; 174*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 175*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD case slave_selectmap: 176*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ret_val = Virtex2_ssm_reloc (desc, reloc_offset); 177*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD break; 178*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 179*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD default: 180*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s: Unsupported interface type, %d\n", 181*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, desc->iface); 182*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 183*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return ret_val; 184*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 185*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 186*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 187*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Virtex-II Slave SelectMap configuration loader. Configuration via 188*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * SelectMap is as follows: 189*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * 1. Set the FPGA's PROG_B line low. 190*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * 2. Set the FPGA's PROG_B line high. Wait for INIT_B to go high. 191*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * 3. Write data to the SelectMap port. If INIT_B goes low at any time 192*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * this process, a configuration error (most likely CRC failure) has 193*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * ocurred. At this point a status word may be read from the 194*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * SelectMap interface to determine the source of the problem (You 195*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * could, for instance, put this in your 'abort' function handler). 196*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * 4. After all data has been written, test the state of the FPGA 197*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * INIT_B and DONE lines. If both are high, configuration has 198*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * succeeded. Congratulations! 199*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 200*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize) 201*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD { 202*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int ret_val = FPGA_FAIL; 203*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD Xilinx_Virtex2_Slave_SelectMap_fns *fn = desc->iface_fns; 204*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 205*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF ("%s:%d: Start with interface functions @ 0x%p\n", 206*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, __LINE__, fn); 207*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 208*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (fn) { 209*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD size_t bytecount = 0; 210*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD unsigned char *data = (unsigned char *) buf; 211*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int cookie = desc->cookie; 212*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD unsigned long ts; 213*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 214*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Gotta split this one up (so the stack won't blow??) */ 215*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF ("%s:%d: Function Table:\n" 216*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " base 0x%p\n" 217*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " struct 0x%p\n" 218*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " pre 0x%p\n" 219*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " prog 0x%p\n" 220*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " init 0x%p\n" 221*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " error 0x%p\n", 222*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, __LINE__, 223*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD &fn, fn, fn->pre, fn->pgm, fn->init, fn->err); 224*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF (" clock 0x%p\n" 225*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " cs 0x%p\n" 226*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " write 0x%p\n" 227*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " rdata 0x%p\n" 228*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " wdata 0x%p\n" 229*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " busy 0x%p\n" 230*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " abort 0x%p\n" 231*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " post 0x%p\n\n", 232*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, 233*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD fn->busy, fn->abort, fn->post); 234*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 235*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK 236*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("Initializing FPGA Device %d...\n", cookie); 237*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 238*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 239*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Run the pre configuration function if there is one. 240*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 241*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (*fn->pre) { 242*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->pre) (cookie); 243*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 244*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 245*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 246*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Assert the program line. The minimum pulse width for 247*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Virtex II devices is 300 nS (Tprogram parameter in datasheet). 248*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * There is no maximum value for the pulse width. Check to make 249*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * sure that INIT_B goes low after assertion of PROG_B 250*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 251*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->pgm) (TRUE, TRUE, cookie); 252*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD udelay (10); 253*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ts = get_timer (0); 254*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD do { 255*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_INIT) { 256*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s:%d: ** Timeout after %d ticks waiting for INIT" 257*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " to assert.\n", __FUNCTION__, __LINE__, 258*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_SYS_FPGA_WAIT_INIT); 259*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->abort) (cookie); 260*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_FAIL; 261*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 262*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } while (!(*fn->init) (cookie)); 263*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 264*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->pgm) (FALSE, TRUE, cookie); 265*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY (); 266*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->clk) (TRUE, TRUE, cookie); 267*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 268*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 269*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Start a timer and wait for INIT_B to go high 270*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 271*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ts = get_timer (0); 272*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD do { 273*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY (); 274*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_INIT) { 275*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s:%d: ** Timeout after %d ticks waiting for INIT" 276*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " to deassert.\n", __FUNCTION__, __LINE__, 277*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_SYS_FPGA_WAIT_INIT); 278*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->abort) (cookie); 279*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_FAIL; 280*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 281*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } while ((*fn->init) (cookie) && (*fn->busy) (cookie)); 282*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 283*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->wr) (TRUE, TRUE, cookie); 284*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->cs) (TRUE, TRUE, cookie); 285*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 286*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD udelay (10000); 287*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 288*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 289*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Load the data byte by byte 290*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 291*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD while (bytecount < bsize) { 292*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_CHECK_CTRLC 293*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (ctrlc ()) { 294*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->abort) (cookie); 295*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_FAIL; 296*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 297*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 298*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 299*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if ((*fn->done) (cookie) == FPGA_SUCCESS) { 300*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF ("%s:%d:done went active early, bytecount = %d\n", 301*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, __LINE__, bytecount); 302*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD break; 303*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 304*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 305*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_CHECK_ERROR 306*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if ((*fn->init) (cookie)) { 307*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("\n%s:%d: ** Error: INIT asserted during" 308*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " configuration\n", __FUNCTION__, __LINE__); 309*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%d = buffer offset, %d = buffer size\n", 310*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD bytecount, bsize); 311*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->abort) (cookie); 312*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_FAIL; 313*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 314*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 315*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 316*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->wdata) (data[bytecount++], TRUE, cookie); 317*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY (); 318*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 319*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 320*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Cycle the clock pin 321*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 322*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->clk) (FALSE, TRUE, cookie); 323*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY (); 324*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->clk) (TRUE, TRUE, cookie); 325*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 326*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_CHECK_BUSY 327*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ts = get_timer (0); 328*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD while ((*fn->busy) (cookie)) { 329*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_BUSY) { 330*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s:%d: ** Timeout after %d ticks waiting for" 331*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD " BUSY to deassert\n", 332*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, __LINE__, CONFIG_SYS_FPGA_WAIT_BUSY); 333*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->abort) (cookie); 334*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_FAIL; 335*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 336*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 337*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 338*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 339*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK 340*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (bytecount % (bsize / 40) == 0) 341*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD putc ('.'); 342*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 343*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 344*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 345*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 346*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Finished writing the data; deassert FPGA CS_B and WRITE_B signals. 347*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 348*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY (); 349*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->cs) (FALSE, TRUE, cookie); 350*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->wr) (FALSE, TRUE, cookie); 351*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 352*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK 353*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD putc ('\n'); 354*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 355*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 356*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 357*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Check for successful configuration. FPGA INIT_B and DONE should 358*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * both be high upon successful configuration. 359*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 360*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ts = get_timer (0); 361*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ret_val = FPGA_SUCCESS; 362*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD while (((*fn->done) (cookie) == FPGA_FAIL) || (*fn->init) (cookie)) { 363*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_CONFIG) { 364*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s:%d: ** Timeout after %d ticks waiting for DONE to" 365*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD "assert and INIT to deassert\n", 366*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, __LINE__, CONFIG_SYS_FPGA_WAIT_CONFIG); 367*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->abort) (cookie); 368*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ret_val = FPGA_FAIL; 369*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD break; 370*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 371*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 372*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 373*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (ret_val == FPGA_SUCCESS) { 374*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK 375*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("Initialization of FPGA device %d complete\n", cookie); 376*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 377*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 378*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Run the post configuration function if there is one. 379*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 380*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (*fn->post) { 381*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->post) (cookie); 382*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 383*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } else { 384*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK 385*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("** Initialization of FPGA device %d FAILED\n", 386*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD cookie); 387*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 388*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 389*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } else { 390*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s:%d: NULL Interface function table!\n", 391*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, __LINE__); 392*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 393*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return ret_val; 394*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 395*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 396*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 397*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Read the FPGA configuration data 398*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 399*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int Virtex2_ssm_dump (Xilinx_desc * desc, void *buf, size_t bsize) 400*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD { 401*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int ret_val = FPGA_FAIL; 402*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD Xilinx_Virtex2_Slave_SelectMap_fns *fn = desc->iface_fns; 403*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 404*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (fn) { 405*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD unsigned char *data = (unsigned char *) buf; 406*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD size_t bytecount = 0; 407*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int cookie = desc->cookie; 408*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 409*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("Starting Dump of FPGA Device %d...\n", cookie); 410*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 411*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->cs) (TRUE, TRUE, cookie); 412*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->clk) (TRUE, TRUE, cookie); 413*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 414*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD while (bytecount < bsize) { 415*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_CHECK_CTRLC 416*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (ctrlc ()) { 417*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->abort) (cookie); 418*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_FAIL; 419*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 420*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 421*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 422*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Cycle the clock and read the data 423*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 424*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->clk) (FALSE, TRUE, cookie); 425*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->clk) (TRUE, TRUE, cookie); 426*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->rdata) (&(data[bytecount++]), cookie); 427*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK 428*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (bytecount % (bsize / 40) == 0) 429*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD putc ('.'); 430*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 431*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 432*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 433*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 434*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Deassert CS_B and cycle the clock to deselect the device. 435*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 436*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->cs) (FALSE, FALSE, cookie); 437*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->clk) (FALSE, TRUE, cookie); 438*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->clk) (TRUE, TRUE, cookie); 439*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 440*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK 441*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD putc ('\n'); 442*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif 443*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD puts ("Done.\n"); 444*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } else { 445*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s:%d: NULL Interface function table!\n", 446*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, __LINE__); 447*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 448*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return ret_val; 449*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 450*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 451*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 452*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Relocate the addresses in the function table from FLASH (or ROM, 453*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * or whatever) to RAM. 454*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 455*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int Virtex2_ssm_reloc (Xilinx_desc * desc, ulong reloc_offset) 456*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD { 457*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ulong addr; 458*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int ret_val = FPGA_FAIL; 459*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD Xilinx_Virtex2_Slave_SelectMap_fns *fn_r, *fn = 460*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (Xilinx_Virtex2_Slave_SelectMap_fns *) (desc->iface_fns); 461*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 462*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (fn) { 463*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 464*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Get the relocated table address 465*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 466*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD addr = (ulong) fn + reloc_offset; 467*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD fn_r = (Xilinx_Virtex2_Slave_SelectMap_fns *) addr; 468*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 469*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* 470*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Check to see if the table has already been relocated. If not, do 471*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * a sanity check to make sure there is a faithful copy of the 472*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * FLASH based function table in RAM, then adjust the table. 473*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */ 474*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (!fn_r->relocated) { 475*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (memcmp 476*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (fn_r, fn, sizeof (Xilinx_Virtex2_Slave_SelectMap_fns)) 477*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD == 0) { 478*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD desc->iface_fns = fn_r; 479*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } else { 480*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF ("%s:%d: Invalid function table at 0x%p\n", 481*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, __LINE__, fn_r); 482*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_FAIL; 483*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 484*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 485*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF ("%s:%d: Relocating descriptor at 0x%p\n", 486*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, __LINE__, desc); 487*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 488*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD addr = (ulong) (fn->pre) + reloc_offset; 489*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD fn_r->pre = (Xilinx_pre_fn) addr; 490*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD addr = (ulong) (fn->pgm) + reloc_offset; 491*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD fn_r->pgm = (Xilinx_pgm_fn) addr; 492*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD addr = (ulong) (fn->init) + reloc_offset; 493*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD fn_r->init = (Xilinx_init_fn) addr; 494*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD addr = (ulong) (fn->done) + reloc_offset; 495*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD fn_r->done = (Xilinx_done_fn) addr; 496*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD addr = (ulong) (fn->err) + reloc_offset; 497*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD fn_r->err = (Xilinx_err_fn) addr; 498*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD addr = (ulong) (fn->clk) + reloc_offset; 499*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD fn_r->clk = (Xilinx_clk_fn) addr; 500*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD addr = (ulong) (fn->cs) + reloc_offset; 501*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD fn_r->cs = (Xilinx_cs_fn) addr; 502*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD addr = (ulong) (fn->wr) + reloc_offset; 503*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD fn_r->wr = (Xilinx_wr_fn) addr; 504*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD addr = (ulong) (fn->rdata) + reloc_offset; 505*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD fn_r->rdata = (Xilinx_rdata_fn) addr; 506*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD addr = (ulong) (fn->wdata) + reloc_offset; 507*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD fn_r->wdata = (Xilinx_wdata_fn) addr; 508*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD addr = (ulong) (fn->busy) + reloc_offset; 509*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD fn_r->busy = (Xilinx_busy_fn) addr; 510*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD addr = (ulong) (fn->abort) + reloc_offset; 511*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD fn_r->abort = (Xilinx_abort_fn) addr; 512*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD addr = (ulong) (fn->post) + reloc_offset; 513*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD fn_r->post = (Xilinx_post_fn) addr; 514*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD fn_r->relocated = TRUE; 515*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } else { 516*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s:%d: Function table @0x%p has already been relocated\n", __FUNCTION__, __LINE__, fn_r); 517*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD desc->iface_fns = fn_r; 518*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 519*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ret_val = FPGA_SUCCESS; 520*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } else { 521*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s: NULL Interface function table!\n", __FUNCTION__); 522*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 523*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return ret_val; 524*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 525*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 526*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int Virtex2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize) 527*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD { 528*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s: Slave Serial Loading is unsupported\n", __FUNCTION__); 529*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_FAIL; 530*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 531*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 532*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int Virtex2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize) 533*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD { 534*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s: Slave Serial Dumping is unsupported\n", __FUNCTION__); 535*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_FAIL; 536*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 537*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 538*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD static int Virtex2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset) 539*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD { 540*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int ret_val = FPGA_FAIL; 541*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD Xilinx_Virtex2_Slave_Serial_fns *fn = 542*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (Xilinx_Virtex2_Slave_Serial_fns *) (desc->iface_fns); 543*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 544*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (fn) { 545*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s:%d: Slave Serial Loading is unsupported\n", 546*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, __LINE__); 547*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } else { 548*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s:%d: NULL Interface function table!\n", 549*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, __LINE__); 550*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 551*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return ret_val; 552*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } 553*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD 554*c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* vim: set ts=4 tw=78: */ 555