]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/fpga/stratixII.c
Merge branch 'master' of git://git.denx.de/u-boot-arm
[karo-tx-uboot.git] / drivers / fpga / 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 int StratixII_ps_fpp_load (Altera_desc * desc, void *buf, size_t bsize,
29                            int isSerial, int isSecure);
30 int StratixII_ps_fpp_dump (Altera_desc * desc, void *buf, size_t bsize);
31
32 /****************************************************************/
33 /* Stratix II Generic Implementation                            */
34 int StratixII_load (Altera_desc * desc, void *buf, size_t bsize)
35 {
36         int ret_val = FPGA_FAIL;
37
38         switch (desc->iface) {
39         case passive_serial:
40                 ret_val = StratixII_ps_fpp_load (desc, buf, bsize, 1, 0);
41                 break;
42         case fast_passive_parallel:
43                 ret_val = StratixII_ps_fpp_load (desc, buf, bsize, 0, 0);
44                 break;
45         case fast_passive_parallel_security:
46                 ret_val = StratixII_ps_fpp_load (desc, buf, bsize, 0, 1);
47                 break;
48
49                 /* Add new interface types here */
50         default:
51                 printf ("%s: Unsupported interface type, %d\n", __FUNCTION__,
52                         desc->iface);
53         }
54         return ret_val;
55 }
56
57 int StratixII_dump (Altera_desc * desc, void *buf, size_t bsize)
58 {
59         int ret_val = FPGA_FAIL;
60
61         switch (desc->iface) {
62         case passive_serial:
63         case fast_passive_parallel:
64         case fast_passive_parallel_security:
65                 ret_val = StratixII_ps_fpp_dump (desc, buf, bsize);
66                 break;
67                 /* Add new interface types here */
68         default:
69                 printf ("%s: Unsupported interface type, %d\n", __FUNCTION__,
70                         desc->iface);
71         }
72         return ret_val;
73 }
74
75 int StratixII_info (Altera_desc * desc)
76 {
77         return FPGA_SUCCESS;
78 }
79
80 int StratixII_ps_fpp_dump (Altera_desc * desc, void *buf, size_t bsize)
81 {
82         printf ("Stratix II Fast Passive Parallel dump is not implemented\n");
83         return FPGA_FAIL;
84 }
85
86 int StratixII_ps_fpp_load (Altera_desc * desc, void *buf, size_t bsize,
87                            int isSerial, int isSecure)
88 {
89         altera_board_specific_func *fns;
90         int cookie;
91         int ret_val = FPGA_FAIL;
92         int bytecount;
93         char *buff = buf;
94         int i;
95
96         if (!desc) {
97                 printf ("%s(%d) Altera_desc missing\n", __FUNCTION__, __LINE__);
98                 return FPGA_FAIL;
99         }
100         if (!buff) {
101                 printf ("%s(%d) buffer is missing\n", __FUNCTION__, __LINE__);
102                 return FPGA_FAIL;
103         }
104         if (!bsize) {
105                 printf ("%s(%d) size is zero\n", __FUNCTION__, __LINE__);
106                 return FPGA_FAIL;
107         }
108         if (!desc->iface_fns) {
109                 printf
110                     ("%s(%d) Altera_desc function interface table is missing\n",
111                      __FUNCTION__, __LINE__);
112                 return FPGA_FAIL;
113         }
114         fns = (altera_board_specific_func *) (desc->iface_fns);
115         cookie = desc->cookie;
116
117         if (!
118             (fns->config && fns->status && fns->done && fns->data
119              && fns->abort)) {
120                 printf
121                     ("%s(%d) Missing some function in the function interface table\n",
122                      __FUNCTION__, __LINE__);
123                 return FPGA_FAIL;
124         }
125
126         /* 1. give board specific a chance to do anything before we start */
127         if (fns->pre) {
128                 if ((ret_val = fns->pre (cookie)) < 0) {
129                         return ret_val;
130                 }
131         }
132
133         /* from this point on we must fail gracfully by calling lower layer abort */
134
135         /* 2. Strat burn cycle by deasserting config for t_CFG and waiting t_CF2CK after reaserted */
136         fns->config (0, 1, cookie);
137         udelay (5);             /* nCONFIG low pulse width 2usec */
138         fns->config (1, 1, cookie);
139         udelay (100);           /* nCONFIG high to first rising edge on DCLK */
140
141         /* 3. Start the Data cycle with clk deasserted */
142         bytecount = 0;
143         fns->clk (0, 1, cookie);
144
145         printf ("loading to fpga    ");
146         while (bytecount < bsize) {
147                 /* 3.1 check stratix has not signaled us an error */
148                 if (fns->status (cookie) != 1) {
149                         printf
150                             ("\n%s(%d) Stratix failed (byte transfered till failure 0x%x)\n",
151                              __FUNCTION__, __LINE__, bytecount);
152                         fns->abort (cookie);
153                         return FPGA_FAIL;
154                 }
155                 if (isSerial) {
156                         int i;
157                         uint8_t data = buff[bytecount++];
158                         for (i = 0; i < 8; i++) {
159                                 /* 3.2(ps) put data on the bus */
160                                 fns->data ((data >> i) & 1, 1, cookie);
161
162                                 /* 3.3(ps) clock once */
163                                 fns->clk (1, 1, cookie);
164                                 fns->clk (0, 1, cookie);
165                         }
166                 } else {
167                         /* 3.2(fpp) put data on the bus */
168                         fns->data (buff[bytecount++], 1, cookie);
169
170                         /* 3.3(fpp) clock once */
171                         fns->clk (1, 1, cookie);
172                         fns->clk (0, 1, cookie);
173
174                         /* 3.4(fpp) for secure cycle push 3 more  clocks */
175                         for (i = 0; isSecure && i < 3; i++) {
176                                 fns->clk (1, 1, cookie);
177                                 fns->clk (0, 1, cookie);
178                         }
179                 }
180
181                 /* 3.5 while clk is deasserted it is safe to print some progress indication */
182                 if ((bytecount % (bsize / 100)) == 0) {
183                         printf ("\b\b\b%02d\%", bytecount * 100 / bsize);
184                 }
185         }
186
187         /* 4. Set one last clock and check conf done signal */
188         fns->clk (1, 1, cookie);
189         udelay (100);
190         if (!fns->done (cookie)) {
191                 printf (" error!.\n");
192                 fns->abort (cookie);
193                 return FPGA_FAIL;
194         } else {
195                 printf ("\b\b\b done.\n");
196         }
197
198         /* 5. call lower layer post configuration */
199         if (fns->post) {
200                 if ((ret_val = fns->post (cookie)) < 0) {
201                         fns->abort (cookie);
202                         return ret_val;
203                 }
204         }
205
206         return FPGA_SUCCESS;
207 }