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