Merge branch 'master' of git://git.denx.de/u-boot-at91
[platform/kernel/u-boot.git] / common / stratixII.c
1 /*
2  * (C) Copyright 2007
3  * Eran Liberty, Extricom , eran.liberty@gmail.com
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  *
23  */
24
25 #include <common.h>             /* core U-Boot definitions */
26 #include <altera.h>
27
28 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ALTERA) && defined(CONFIG_FPGA_STRATIX_II)
29
30 int StratixII_ps_fpp_load (Altera_desc * desc, void *buf, size_t bsize,
31                            int isSerial, int isSecure);
32 int StratixII_ps_fpp_dump (Altera_desc * desc, void *buf, size_t bsize);
33
34 /****************************************************************/
35 /* Stratix II Generic Implementation                            */
36 int StratixII_load (Altera_desc * desc, void *buf, size_t bsize)
37 {
38         int ret_val = FPGA_FAIL;
39
40         switch (desc->iface) {
41         case passive_serial:
42                 ret_val = StratixII_ps_fpp_load (desc, buf, bsize, 1, 0);
43                 break;
44         case fast_passive_parallel:
45                 ret_val = StratixII_ps_fpp_load (desc, buf, bsize, 0, 0);
46                 break;
47         case fast_passive_parallel_security:
48                 ret_val = StratixII_ps_fpp_load (desc, buf, bsize, 0, 1);
49                 break;
50
51                 /* Add new interface types here */
52         default:
53                 printf ("%s: Unsupported interface type, %d\n", __FUNCTION__,
54                         desc->iface);
55         }
56         return ret_val;
57 }
58
59 int StratixII_dump (Altera_desc * desc, void *buf, size_t bsize)
60 {
61         int ret_val = FPGA_FAIL;
62
63         switch (desc->iface) {
64         case passive_serial:
65         case fast_passive_parallel:
66         case fast_passive_parallel_security:
67                 ret_val = StratixII_ps_fpp_dump (desc, buf, bsize);
68                 break;
69                 /* Add new interface types here */
70         default:
71                 printf ("%s: Unsupported interface type, %d\n", __FUNCTION__,
72                         desc->iface);
73         }
74         return ret_val;
75 }
76
77 int StratixII_info (Altera_desc * desc)
78 {
79         return FPGA_SUCCESS;
80 }
81
82 int StratixII_reloc (Altera_desc * desc, ulong reloc_offset)
83 {
84         int i;
85         uint32_t dest = (uint32_t) desc & 0xff000000;
86
87         /* we assume a relocated code and non relocated code has different upper 8 bits */
88         if (dest != ((uint32_t) desc->iface_fns & 0xff000000)) {
89                 desc->iface_fns =
90                     (void *)((uint32_t) (desc->iface_fns) + reloc_offset);
91         }
92         for (i = 0; i < sizeof (altera_board_specific_func) / sizeof (void *);
93              i++) {
94                 if (dest !=
95                     ((uint32_t) (((void **)(desc->iface_fns))[i]) & 0xff000000))
96                 {
97                         ((void **)(desc->iface_fns))[i] =
98                             (void
99                              *)(((uint32_t) (((void **)(desc->iface_fns))[i])) +
100                                 reloc_offset);
101                 }
102         }
103         return FPGA_SUCCESS;
104 }
105
106 int StratixII_ps_fpp_dump (Altera_desc * desc, void *buf, size_t bsize)
107 {
108         printf ("Stratix II Fast Passive Parallel dump is not implemented\n");
109         return FPGA_FAIL;
110 }
111
112 int StratixII_ps_fpp_load (Altera_desc * desc, void *buf, size_t bsize,
113                            int isSerial, int isSecure)
114 {
115         altera_board_specific_func *fns;
116         int cookie;
117         int ret_val = FPGA_FAIL;
118         int bytecount;
119         char *buff = buf;
120         int i;
121
122         if (!desc) {
123                 printf ("%s(%d) Altera_desc missing\n", __FUNCTION__, __LINE__);
124                 return FPGA_FAIL;
125         }
126         if (!buff) {
127                 printf ("%s(%d) buffer is missing\n", __FUNCTION__, __LINE__);
128                 return FPGA_FAIL;
129         }
130         if (!bsize) {
131                 printf ("%s(%d) size is zero\n", __FUNCTION__, __LINE__);
132                 return FPGA_FAIL;
133         }
134         if (!desc->iface_fns) {
135                 printf
136                     ("%s(%d) Altera_desc function interface table is missing\n",
137                      __FUNCTION__, __LINE__);
138                 return FPGA_FAIL;
139         }
140         fns = (altera_board_specific_func *) (desc->iface_fns);
141         cookie = desc->cookie;
142
143         if (!
144             (fns->config && fns->status && fns->done && fns->data
145              && fns->abort)) {
146                 printf
147                     ("%s(%d) Missing some function in the function interface table\n",
148                      __FUNCTION__, __LINE__);
149                 return FPGA_FAIL;
150         }
151
152         /* 1. give board specific a chance to do anything before we start */
153         if (fns->pre) {
154                 if ((ret_val = fns->pre (cookie)) < 0) {
155                         return ret_val;
156                 }
157         }
158
159         /* from this point on we must fail gracfully by calling lower layer abort */
160
161         /* 2. Strat burn cycle by deasserting config for t_CFG and waiting t_CF2CK after reaserted */
162         fns->config (0, 1, cookie);
163         udelay (5);             /* nCONFIG low pulse width 2usec */
164         fns->config (1, 1, cookie);
165         udelay (100);           /* nCONFIG high to first rising edge on DCLK */
166
167         /* 3. Start the Data cycle with clk deasserted */
168         bytecount = 0;
169         fns->clk (0, 1, cookie);
170
171         printf ("loading to fpga    ");
172         while (bytecount < bsize) {
173                 /* 3.1 check stratix has not signaled us an error */
174                 if (fns->status (cookie) != 1) {
175                         printf
176                             ("\n%s(%d) Stratix failed (byte transfered till failure 0x%x)\n",
177                              __FUNCTION__, __LINE__, bytecount);
178                         fns->abort (cookie);
179                         return FPGA_FAIL;
180                 }
181                 if (isSerial) {
182                         int i;
183                         uint8_t data = buff[bytecount++];
184                         for (i = 0; i < 8; i++) {
185                                 /* 3.2(ps) put data on the bus */
186                                 fns->data ((data >> i) & 1, 1, cookie);
187
188                                 /* 3.3(ps) clock once */
189                                 fns->clk (1, 1, cookie);
190                                 fns->clk (0, 1, cookie);
191                         }
192                 } else {
193                         /* 3.2(fpp) put data on the bus */
194                         fns->data (buff[bytecount++], 1, cookie);
195
196                         /* 3.3(fpp) clock once */
197                         fns->clk (1, 1, cookie);
198                         fns->clk (0, 1, cookie);
199
200                         /* 3.4(fpp) for secure cycle push 3 more  clocks */
201                         for (i = 0; isSecure && i < 3; i++) {
202                                 fns->clk (1, 1, cookie);
203                                 fns->clk (0, 1, cookie);
204                         }
205                 }
206
207                 /* 3.5 while clk is deasserted it is safe to print some progress indication */
208                 if ((bytecount % (bsize / 100)) == 0) {
209                         printf ("\b\b\b%02d\%", bytecount * 100 / bsize);
210                 }
211         }
212
213         /* 4. Set one last clock and check conf done signal */
214         fns->clk (1, 1, cookie);
215         udelay (100);
216         if (!fns->done (cookie)) {
217                 printf (" error!.\n");
218                 fns->abort (cookie);
219                 return FPGA_FAIL;
220         } else {
221                 printf ("\b\b\b done.\n");
222         }
223
224         /* 5. call lower layer post configuration */
225         if (fns->post) {
226                 if ((ret_val = fns->post (cookie)) < 0) {
227                         fns->abort (cookie);
228                         return ret_val;
229                 }
230         }
231
232         return FPGA_SUCCESS;
233 }
234
235 #endif                          /* defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ALTERA) && defined(CONFIG_FPGA_STRATIX_II) */