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