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