1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /*
3c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * (C) Copyright 2002
4c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
5c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */
6c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
7c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #include <common.h> /* core U-Boot definitions */
8c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #include <spartan2.h> /* Spartan-II device family */
9c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
10c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Define FPGA_DEBUG to get debug printf's */
11c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef FPGA_DEBUG
12c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define PRINTF(fmt,args...) printf (fmt ,##args)
13c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #else
14c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define PRINTF(fmt,args...)
15c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
16c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
17c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #undef CONFIG_SYS_FPGA_CHECK_BUSY
18c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #undef CONFIG_SYS_FPGA_PROG_FEEDBACK
19c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
20c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Note: The assumption is that we cannot possibly run fast enough to
21c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * overrun the device (the Slave Parallel mode can free run at 50MHz).
22c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * If there is a need to operate slower, define CONFIG_FPGA_DELAY in
23c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * the board config file to slow things down.
24c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */
25c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_FPGA_DELAY
26c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_FPGA_DELAY()
27c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
28c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
29c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifndef CONFIG_SYS_FPGA_WAIT
30c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/100 /* 10 ms */
31c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
32c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
33f8c1be98SMichal Simek static int spartan2_sp_load(xilinx_desc *desc, const void *buf, size_t bsize);
34f8c1be98SMichal Simek static int spartan2_sp_dump(xilinx_desc *desc, const void *buf, size_t bsize);
35f8c1be98SMichal Simek /* static int spartan2_sp_info(xilinx_desc *desc ); */
36c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
37f8c1be98SMichal Simek static int spartan2_ss_load(xilinx_desc *desc, const void *buf, size_t bsize);
38f8c1be98SMichal Simek static int spartan2_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize);
39f8c1be98SMichal Simek /* static int spartan2_ss_info(xilinx_desc *desc ); */
40c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
41c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* ------------------------------------------------------------------------- */
42c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Spartan-II Generic Implementation */
spartan2_load(xilinx_desc * desc,const void * buf,size_t bsize,bitstream_type bstype)437a78bd26SMichal Simek static int spartan2_load(xilinx_desc *desc, const void *buf, size_t bsize,
447a78bd26SMichal Simek bitstream_type bstype)
45c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
46c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int ret_val = FPGA_FAIL;
47c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
48c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD switch (desc->iface) {
49c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD case slave_serial:
50c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__);
51b625b9aeSMichal Simek ret_val = spartan2_ss_load(desc, buf, bsize);
52c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD break;
53c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
54c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD case slave_parallel:
55c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__);
56b625b9aeSMichal Simek ret_val = spartan2_sp_load(desc, buf, bsize);
57c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD break;
58c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
59c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD default:
60c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s: Unsupported interface type, %d\n",
61c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, desc->iface);
62c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
63c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
64c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return ret_val;
65c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
66c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
spartan2_dump(xilinx_desc * desc,const void * buf,size_t bsize)6714cfc4f3SMichal Simek static int spartan2_dump(xilinx_desc *desc, const void *buf, size_t bsize)
68c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
69c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int ret_val = FPGA_FAIL;
70c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
71c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD switch (desc->iface) {
72c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD case slave_serial:
73c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__);
74b625b9aeSMichal Simek ret_val = spartan2_ss_dump(desc, buf, bsize);
75c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD break;
76c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
77c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD case slave_parallel:
78c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__);
79b625b9aeSMichal Simek ret_val = spartan2_sp_dump(desc, buf, bsize);
80c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD break;
81c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
82c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD default:
83c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s: Unsupported interface type, %d\n",
84c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, desc->iface);
85c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
86c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
87c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return ret_val;
88c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
89c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
spartan2_info(xilinx_desc * desc)9014cfc4f3SMichal Simek static int spartan2_info(xilinx_desc *desc)
91c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
92c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_SUCCESS;
93c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
94c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
95c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
96c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* ------------------------------------------------------------------------- */
97c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Spartan-II Slave Parallel Generic Implementation */
98c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
spartan2_sp_load(xilinx_desc * desc,const void * buf,size_t bsize)99f8c1be98SMichal Simek static int spartan2_sp_load(xilinx_desc *desc, const void *buf, size_t bsize)
100c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
101c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int ret_val = FPGA_FAIL; /* assume the worst */
102b625b9aeSMichal Simek xilinx_spartan2_slave_parallel_fns *fn = desc->iface_fns;
103c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
104c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF ("%s: start with interface functions @ 0x%p\n",
105c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, fn);
106c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
107c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (fn) {
108c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD size_t bytecount = 0;
109c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD unsigned char *data = (unsigned char *) buf;
110c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int cookie = desc->cookie; /* make a local copy */
111c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD unsigned long ts; /* timestamp */
112c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
113c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF ("%s: Function Table:\n"
114c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD "ptr:\t0x%p\n"
115c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD "struct: 0x%p\n"
116c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD "pre: 0x%p\n"
117c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD "pgm:\t0x%p\n"
118c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD "init:\t0x%p\n"
119c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD "err:\t0x%p\n"
120c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD "clk:\t0x%p\n"
121c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD "cs:\t0x%p\n"
122c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD "wr:\t0x%p\n"
123c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD "read data:\t0x%p\n"
124c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD "write data:\t0x%p\n"
125c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD "busy:\t0x%p\n"
126c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD "abort:\t0x%p\n",
127c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD "post:\t0x%p\n\n",
128c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, &fn, fn, fn->pre, fn->pgm, fn->init, fn->err,
129c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, fn->busy,
130c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD fn->abort, fn->post);
131c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
132c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /*
133c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * This code is designed to emulate the "Express Style"
134c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Continuous Data Loading in Slave Parallel Mode for
135c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * the Spartan-II Family.
136c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */
137c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
138c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("Loading FPGA Device %d...\n", cookie);
139c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
140c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /*
141c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Run the pre configuration function if there is one.
142c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */
143c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (*fn->pre) {
144c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->pre) (cookie);
145c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
146c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
147c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Establish the initial state */
148472d5460SYork Sun (*fn->pgm) (true, true, cookie); /* Assert the program, commit */
149c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
150c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Get ready for the burn */
151c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY ();
152472d5460SYork Sun (*fn->pgm) (false, true, cookie); /* Deassert the program, commit */
153c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
154c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ts = get_timer (0); /* get current time */
155c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Now wait for INIT and BUSY to go high */
156c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD do {
157c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY ();
158c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
159c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD puts ("** Timeout waiting for INIT to clear.\n");
160c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->abort) (cookie); /* abort the burn */
161c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_FAIL;
162c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
163c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } while ((*fn->init) (cookie) && (*fn->busy) (cookie));
164c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
165472d5460SYork Sun (*fn->wr) (true, true, cookie); /* Assert write, commit */
166472d5460SYork Sun (*fn->cs) (true, true, cookie); /* Assert chip select, commit */
167472d5460SYork Sun (*fn->clk) (true, true, cookie); /* Assert the clock pin */
168c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
169c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Load the data */
170c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD while (bytecount < bsize) {
171c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* XXX - do we check for an Ctrl-C press in here ??? */
172c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* XXX - Check the error bit? */
173c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
174472d5460SYork Sun (*fn->wdata) (data[bytecount++], true, cookie); /* write the data */
175c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY ();
176472d5460SYork Sun (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
177c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY ();
178472d5460SYork Sun (*fn->clk) (true, true, cookie); /* Assert the clock pin */
179c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
180c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_CHECK_BUSY
181c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ts = get_timer (0); /* get current time */
182c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD while ((*fn->busy) (cookie)) {
183c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* XXX - we should have a check in here somewhere to
184c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * make sure we aren't busy forever... */
185c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
186c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY ();
187472d5460SYork Sun (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
188c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY ();
189472d5460SYork Sun (*fn->clk) (true, true, cookie); /* Assert the clock pin */
190c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
191c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
192c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD puts ("** Timeout waiting for BUSY to clear.\n");
193c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->abort) (cookie); /* abort the burn */
194c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_FAIL;
195c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
196c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
197c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
198c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
199c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
200c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (bytecount % (bsize / 40) == 0)
201c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD putc ('.'); /* let them know we are alive */
202c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
203c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
204c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
205c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY ();
206472d5460SYork Sun (*fn->cs) (false, true, cookie); /* Deassert the chip select */
207472d5460SYork Sun (*fn->wr) (false, true, cookie); /* Deassert the write pin */
208c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
209c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
210c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD putc ('\n'); /* terminate the dotted line */
211c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
212c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
213c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* now check for done signal */
214c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ts = get_timer (0); /* get current time */
215c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ret_val = FPGA_SUCCESS;
216c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD while ((*fn->done) (cookie) == FPGA_FAIL) {
217c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
218c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY ();
219472d5460SYork Sun (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
220c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY ();
221472d5460SYork Sun (*fn->clk) (true, true, cookie); /* Assert the clock pin */
222c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
223c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
224c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD puts ("** Timeout waiting for DONE to clear.\n");
225c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->abort) (cookie); /* abort the burn */
226c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ret_val = FPGA_FAIL;
227c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD break;
228c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
229c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
230c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
231c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /*
232c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Run the post configuration function if there is one.
233c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */
2343818b677SMatthias Fuchs if (*fn->post)
235c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->post) (cookie);
236c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
237c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
2383818b677SMatthias Fuchs if (ret_val == FPGA_SUCCESS)
2393818b677SMatthias Fuchs puts ("Done.\n");
2403818b677SMatthias Fuchs else
241c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD puts ("Fail.\n");
242c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
243c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
244c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } else {
245c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s: NULL Interface function table!\n", __FUNCTION__);
246c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
247c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
248c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return ret_val;
249c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
250c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
spartan2_sp_dump(xilinx_desc * desc,const void * buf,size_t bsize)251f8c1be98SMichal Simek static int spartan2_sp_dump(xilinx_desc *desc, const void *buf, size_t bsize)
252c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
253c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int ret_val = FPGA_FAIL; /* assume the worst */
254b625b9aeSMichal Simek xilinx_spartan2_slave_parallel_fns *fn = desc->iface_fns;
255c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
256c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (fn) {
257c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD unsigned char *data = (unsigned char *) buf;
258c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD size_t bytecount = 0;
259c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int cookie = desc->cookie; /* make a local copy */
260c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
261c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("Starting Dump of FPGA Device %d...\n", cookie);
262c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
263472d5460SYork Sun (*fn->cs) (true, true, cookie); /* Assert chip select, commit */
264472d5460SYork Sun (*fn->clk) (true, true, cookie); /* Assert the clock pin */
265c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
266c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* dump the data */
267c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD while (bytecount < bsize) {
268c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* XXX - do we check for an Ctrl-C press in here ??? */
269c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
270472d5460SYork Sun (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
271472d5460SYork Sun (*fn->clk) (true, true, cookie); /* Assert the clock pin */
272c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->rdata) (&(data[bytecount++]), cookie); /* read the data */
273c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
274c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (bytecount % (bsize / 40) == 0)
275c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD putc ('.'); /* let them know we are alive */
276c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
277c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
278c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
279472d5460SYork Sun (*fn->cs) (false, false, cookie); /* Deassert the chip select */
280472d5460SYork Sun (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
281472d5460SYork Sun (*fn->clk) (true, true, cookie); /* Assert the clock pin */
282c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
283c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
284c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD putc ('\n'); /* terminate the dotted line */
285c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
286c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD puts ("Done.\n");
287c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
288c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* XXX - checksum the data? */
289c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } else {
290c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s: NULL Interface function table!\n", __FUNCTION__);
291c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
292c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
293c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return ret_val;
294c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
295c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
296c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
297c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* ------------------------------------------------------------------------- */
298c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
spartan2_ss_load(xilinx_desc * desc,const void * buf,size_t bsize)299f8c1be98SMichal Simek static int spartan2_ss_load(xilinx_desc *desc, const void *buf, size_t bsize)
300c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
301c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int ret_val = FPGA_FAIL; /* assume the worst */
302b625b9aeSMichal Simek xilinx_spartan2_slave_serial_fns *fn = desc->iface_fns;
303c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int i;
304c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD unsigned char val;
305c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
306c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF ("%s: start with interface functions @ 0x%p\n",
307c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, fn);
308c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
309c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (fn) {
310c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD size_t bytecount = 0;
311c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD unsigned char *data = (unsigned char *) buf;
312c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD int cookie = desc->cookie; /* make a local copy */
313c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD unsigned long ts; /* timestamp */
314c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
315c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD PRINTF ("%s: Function Table:\n"
316c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD "ptr:\t0x%p\n"
317c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD "struct: 0x%p\n"
318c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD "pgm:\t0x%p\n"
319c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD "init:\t0x%p\n"
320c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD "clk:\t0x%p\n"
321c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD "wr:\t0x%p\n"
322c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD "done:\t0x%p\n\n",
323c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__, &fn, fn, fn->pgm, fn->init,
324c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD fn->clk, fn->wr, fn->done);
325c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
326c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("Loading FPGA Device %d...\n", cookie);
327c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
328c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
329c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /*
330c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Run the pre configuration function if there is one.
331c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */
332c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (*fn->pre) {
333c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->pre) (cookie);
334c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
335c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
336c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Establish the initial state */
337472d5460SYork Sun (*fn->pgm) (true, true, cookie); /* Assert the program, commit */
338c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
339c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Wait for INIT state (init low) */
340c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ts = get_timer (0); /* get current time */
341c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD do {
342c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY ();
343c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
344c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD puts ("** Timeout waiting for INIT to start.\n");
345c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_FAIL;
346c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
347c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } while (!(*fn->init) (cookie));
348c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
349c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Get ready for the burn */
350c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY ();
351472d5460SYork Sun (*fn->pgm) (false, true, cookie); /* Deassert the program, commit */
352c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
353c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ts = get_timer (0); /* get current time */
354c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Now wait for INIT to go high */
355c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD do {
356c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY ();
357c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
358c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD puts ("** Timeout waiting for INIT to clear.\n");
359c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_FAIL;
360c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
361c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } while ((*fn->init) (cookie));
362c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
363c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Load the data */
364c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD while (bytecount < bsize) {
365c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
366c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Xilinx detects an error if INIT goes low (active)
367c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD while DONE is low (inactive) */
368c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) {
369c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD puts ("** CRC error during FPGA load.\n");
370c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return (FPGA_FAIL);
371c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
372c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD val = data [bytecount ++];
373c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD i = 8;
374c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD do {
375c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Deassert the clock */
376472d5460SYork Sun (*fn->clk) (false, true, cookie);
377c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY ();
378c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Write data */
379472d5460SYork Sun (*fn->wr) ((val & 0x80), true, cookie);
380c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY ();
381c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Assert the clock */
382472d5460SYork Sun (*fn->clk) (true, true, cookie);
383c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY ();
384c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD val <<= 1;
385c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD i --;
386c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } while (i > 0);
387c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
388c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
389c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (bytecount % (bsize / 40) == 0)
390c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD putc ('.'); /* let them know we are alive */
391c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
392c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
393c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
394c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY ();
395c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
396c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
397c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD putc ('\n'); /* terminate the dotted line */
398c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
399c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
400c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* now check for done signal */
401c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ts = get_timer (0); /* get current time */
402c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ret_val = FPGA_SUCCESS;
403472d5460SYork Sun (*fn->wr) (true, true, cookie);
404c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
405c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD while (! (*fn->done) (cookie)) {
406c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
407c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY ();
408472d5460SYork Sun (*fn->clk) (false, true, cookie); /* Deassert the clock pin */
409c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD CONFIG_FPGA_DELAY ();
410472d5460SYork Sun (*fn->clk) (true, true, cookie); /* Assert the clock pin */
411c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
412c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD putc ('*');
413c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
414c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */
415c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD puts ("** Timeout waiting for DONE to clear.\n");
416c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD ret_val = FPGA_FAIL;
417c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD break;
418c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
419c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
420c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD putc ('\n'); /* terminate the dotted line */
421c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
422c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /*
423c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD * Run the post configuration function if there is one.
424c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD */
4253818b677SMatthias Fuchs if (*fn->post)
426c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD (*fn->post) (cookie);
427c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
428c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
4293818b677SMatthias Fuchs if (ret_val == FPGA_SUCCESS)
430c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD puts ("Done.\n");
4313818b677SMatthias Fuchs else
432c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD puts ("Fail.\n");
433c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD #endif
434c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
435c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD } else {
436c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s: NULL Interface function table!\n", __FUNCTION__);
437c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
438c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
439c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return ret_val;
440c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
441c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD
spartan2_ss_dump(xilinx_desc * desc,const void * buf,size_t bsize)442f8c1be98SMichal Simek static int spartan2_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize)
443c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD {
444c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* Readback is only available through the Slave Parallel and */
445c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD /* boundary-scan interfaces. */
446c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD printf ("%s: Slave Serial Dumping is unavailable\n",
447c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD __FUNCTION__);
448c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD return FPGA_FAIL;
449c8aa7dfcSJean-Christophe PLAGNIOL-VILLARD }
45014cfc4f3SMichal Simek
45114cfc4f3SMichal Simek struct xilinx_fpga_op spartan2_op = {
45214cfc4f3SMichal Simek .load = spartan2_load,
45314cfc4f3SMichal Simek .dump = spartan2_dump,
45414cfc4f3SMichal Simek .info = spartan2_info,
45514cfc4f3SMichal Simek };
456