]> git.sur5r.net Git - u-boot/blob - drivers/fpga/ACEX1K.c
tools: mkimage: Call fclose in error path
[u-boot] / drivers / fpga / ACEX1K.c
1 /*
2  * (C) Copyright 2003
3  * Steven Scholz, imc Measurement & Control, steven.scholz@imc-berlin.de
4  *
5  * (C) Copyright 2002
6  * Rich Ireland, Enterasys Networks, rireland@enterasys.com.
7  *
8  * SPDX-License-Identifier:     GPL-2.0+
9  */
10
11 #include <common.h>             /* core U-Boot definitions */
12 #include <console.h>
13 #include <ACEX1K.h>             /* ACEX device family */
14
15 /* Define FPGA_DEBUG to get debug printf's */
16 #ifdef  FPGA_DEBUG
17 #define PRINTF(fmt,args...)     printf (fmt ,##args)
18 #else
19 #define PRINTF(fmt,args...)
20 #endif
21
22 /* Note: The assumption is that we cannot possibly run fast enough to
23  * overrun the device (the Slave Parallel mode can free run at 50MHz).
24  * If there is a need to operate slower, define CONFIG_FPGA_DELAY in
25  * the board config file to slow things down.
26  */
27 #ifndef CONFIG_FPGA_DELAY
28 #define CONFIG_FPGA_DELAY()
29 #endif
30
31 #ifndef CONFIG_SYS_FPGA_WAIT
32 #define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/10           /* 100 ms */
33 #endif
34
35 static int ACEX1K_ps_load(Altera_desc *desc, const void *buf, size_t bsize);
36 static int ACEX1K_ps_dump(Altera_desc *desc, const void *buf, size_t bsize);
37 /* static int ACEX1K_ps_info(Altera_desc *desc); */
38
39 /* ------------------------------------------------------------------------- */
40 /* ACEX1K Generic Implementation */
41 int ACEX1K_load(Altera_desc *desc, const void *buf, size_t bsize)
42 {
43         int ret_val = FPGA_FAIL;
44
45         switch (desc->iface) {
46         case passive_serial:
47                 PRINTF ("%s: Launching Passive Serial Loader\n", __FUNCTION__);
48                 ret_val = ACEX1K_ps_load (desc, buf, bsize);
49                 break;
50
51                 /* Add new interface types here */
52
53         default:
54                 printf ("%s: Unsupported interface type, %d\n",
55                                 __FUNCTION__, desc->iface);
56         }
57
58         return ret_val;
59 }
60
61 int ACEX1K_dump(Altera_desc *desc, const void *buf, size_t bsize)
62 {
63         int ret_val = FPGA_FAIL;
64
65         switch (desc->iface) {
66         case passive_serial:
67                 PRINTF ("%s: Launching Passive Serial Dump\n", __FUNCTION__);
68                 ret_val = ACEX1K_ps_dump (desc, buf, bsize);
69                 break;
70
71                 /* Add new interface types here */
72
73         default:
74                 printf ("%s: Unsupported interface type, %d\n",
75                                 __FUNCTION__, desc->iface);
76         }
77
78         return ret_val;
79 }
80
81 int ACEX1K_info( Altera_desc *desc )
82 {
83         return FPGA_SUCCESS;
84 }
85
86
87 /* ------------------------------------------------------------------------- */
88 /* ACEX1K Passive Serial Generic Implementation                                  */
89
90 static int ACEX1K_ps_load(Altera_desc *desc, const void *buf, size_t bsize)
91 {
92         int ret_val = FPGA_FAIL;        /* assume the worst */
93         Altera_ACEX1K_Passive_Serial_fns *fn = desc->iface_fns;
94         int i;
95
96         PRINTF ("%s: start with interface functions @ 0x%p\n",
97                         __FUNCTION__, fn);
98
99         if (fn) {
100                 size_t bytecount = 0;
101                 unsigned char *data = (unsigned char *) buf;
102                 int cookie = desc->cookie;      /* make a local copy */
103                 unsigned long ts;               /* timestamp */
104
105                 PRINTF ("%s: Function Table:\n"
106                                 "ptr:\t0x%p\n"
107                                 "struct: 0x%p\n"
108                                 "config:\t0x%p\n"
109                                 "status:\t0x%p\n"
110                                 "clk:\t0x%p\n"
111                                 "data:\t0x%p\n"
112                                 "done:\t0x%p\n\n",
113                                 __FUNCTION__, &fn, fn, fn->config, fn->status,
114                                 fn->clk, fn->data, fn->done);
115 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
116                 printf ("Loading FPGA Device %d...", cookie);
117 #endif
118
119                 /*
120                  * Run the pre configuration function if there is one.
121                  */
122                 if (*fn->pre) {
123                         (*fn->pre) (cookie);
124                 }
125
126                 /* Establish the initial state */
127                 (*fn->config) (true, true, cookie);     /* Assert nCONFIG */
128
129                 udelay(2);              /* T_cfg > 2us  */
130
131                 /* nSTATUS should be asserted now */
132                 (*fn->done) (cookie);
133                 if ( !(*fn->status) (cookie) ) {
134                         puts ("** nSTATUS is not asserted.\n");
135                         (*fn->abort) (cookie);
136                         return FPGA_FAIL;
137                 }
138
139                 (*fn->config) (false, true, cookie);    /* Deassert nCONFIG */
140                 udelay(2);              /* T_cf2st1 < 4us       */
141
142                 /* Wait for nSTATUS to be released (i.e. deasserted) */
143                 ts = get_timer (0);             /* get current time */
144                 do {
145                         CONFIG_FPGA_DELAY ();
146                         if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) {    /* check the time */
147                                 puts ("** Timeout waiting for STATUS to go high.\n");
148                                 (*fn->abort) (cookie);
149                                 return FPGA_FAIL;
150                         }
151                         (*fn->done) (cookie);
152                 } while ((*fn->status) (cookie));
153
154                 /* Get ready for the burn */
155                 CONFIG_FPGA_DELAY ();
156
157                 /* Load the data */
158                 while (bytecount < bsize) {
159                         unsigned char val=0;
160 #ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
161                         if (ctrlc ()) {
162                                 (*fn->abort) (cookie);
163                                 return FPGA_FAIL;
164                         }
165 #endif
166                         /* Altera detects an error if INIT goes low (active)
167                            while DONE is low (inactive) */
168 #if 0 /* not yet implemented */
169                         if ((*fn->done) (cookie) == 0 && (*fn->init) (cookie)) {
170                                 puts ("** CRC error during FPGA load.\n");
171                                 (*fn->abort) (cookie);
172                                 return (FPGA_FAIL);
173                         }
174 #endif
175                         val = data [bytecount ++ ];
176                         i = 8;
177                         do {
178                                 /* Deassert the clock */
179                                 (*fn->clk) (false, true, cookie);
180                                 CONFIG_FPGA_DELAY ();
181                                 /* Write data */
182                                 (*fn->data) ((val & 0x01), true, cookie);
183                                 CONFIG_FPGA_DELAY ();
184                                 /* Assert the clock */
185                                 (*fn->clk) (true, true, cookie);
186                                 CONFIG_FPGA_DELAY ();
187                                 val >>= 1;
188                                 i --;
189                         } while (i > 0);
190
191 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
192                         if (bytecount % (bsize / 40) == 0)
193                                 putc ('.');             /* let them know we are alive */
194 #endif
195                 }
196
197                 CONFIG_FPGA_DELAY ();
198
199 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
200                 putc (' ');                     /* terminate the dotted line */
201 #endif
202
203         /*
204          * Checking FPGA's CONF_DONE signal - correctly booted ?
205          */
206
207         if ( ! (*fn->done) (cookie) ) {
208                 puts ("** Booting failed! CONF_DONE is still deasserted.\n");
209                 (*fn->abort) (cookie);
210                 return (FPGA_FAIL);
211         }
212
213         /*
214          * "DCLK must be clocked an additional 10 times fpr ACEX 1K..."
215          */
216
217         for (i = 0; i < 12; i++) {
218                 CONFIG_FPGA_DELAY ();
219                 (*fn->clk) (true, true, cookie);        /* Assert the clock pin */
220                 CONFIG_FPGA_DELAY ();
221                 (*fn->clk) (false, true, cookie);       /* Deassert the clock pin */
222         }
223
224         ret_val = FPGA_SUCCESS;
225
226 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
227                 if (ret_val == FPGA_SUCCESS) {
228                         puts ("Done.\n");
229                 }
230                 else {
231                         puts ("Fail.\n");
232                 }
233 #endif
234         (*fn->post) (cookie);
235
236         } else {
237                 printf ("%s: NULL Interface function table!\n", __FUNCTION__);
238         }
239
240         return ret_val;
241 }
242
243 static int ACEX1K_ps_dump(Altera_desc *desc, const void *buf, size_t bsize)
244 {
245         /* Readback is only available through the Slave Parallel and         */
246         /* boundary-scan interfaces.                                         */
247         printf ("%s: Passive Serial Dumping is unavailable\n",
248                         __FUNCTION__);
249         return FPGA_FAIL;
250 }