Merge tag 'efi-2019-10-rc2' of https://gitlab.denx.de/u-boot/custodians/u-boot-efi
[oweals/u-boot.git] / drivers / fpga / cyclon2.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2006
4  * Heiko Schocher, hs@denx.de
5  * Based on ACE1XK.c
6  */
7
8 #include <common.h>             /* core U-Boot definitions */
9 #include <altera.h>
10 #include <ACEX1K.h>             /* ACEX device family */
11
12 /* Define FPGA_DEBUG to get debug printf's */
13 #ifdef  FPGA_DEBUG
14 #define PRINTF(fmt, args...)    printf(fmt, ##args)
15 #else
16 #define PRINTF(fmt, args...)
17 #endif
18
19 /* Note: The assumption is that we cannot possibly run fast enough to
20  * overrun the device (the Slave Parallel mode can free run at 50MHz).
21  * If there is a need to operate slower, define CONFIG_FPGA_DELAY in
22  * the board config file to slow things down.
23  */
24 #ifndef CONFIG_FPGA_DELAY
25 #define CONFIG_FPGA_DELAY()
26 #endif
27
28 #ifndef CONFIG_SYS_FPGA_WAIT
29 #define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ / 10         /* 100 ms */
30 #endif
31
32 static int CYC2_ps_load(Altera_desc *desc, const void *buf, size_t bsize);
33 static int CYC2_ps_dump(Altera_desc *desc, const void *buf, size_t bsize);
34 /* static int CYC2_ps_info( Altera_desc *desc ); */
35
36 /* ------------------------------------------------------------------------- */
37 /* CYCLON2 Generic Implementation */
38 int CYC2_load(Altera_desc *desc, const void *buf, size_t bsize)
39 {
40         int ret_val = FPGA_FAIL;
41
42         switch (desc->iface) {
43         case passive_serial:
44                 PRINTF("%s: Launching Passive Serial Loader\n", __func__);
45                 ret_val = CYC2_ps_load(desc, buf, bsize);
46                 break;
47
48         case fast_passive_parallel:
49                 /* Fast Passive Parallel (FPP) and PS only differ in what is
50                  * done in the write() callback. Use the existing PS load
51                  * function for FPP, too.
52                  */
53                 PRINTF("%s: Launching Fast Passive Parallel Loader\n",
54                        __func__);
55                 ret_val = CYC2_ps_load(desc, buf, bsize);
56                 break;
57
58                 /* Add new interface types here */
59
60         default:
61                 printf("%s: Unsupported interface type, %d\n",
62                        __func__, desc->iface);
63         }
64
65         return ret_val;
66 }
67
68 int CYC2_dump(Altera_desc *desc, const void *buf, size_t bsize)
69 {
70         int ret_val = FPGA_FAIL;
71
72         switch (desc->iface) {
73         case passive_serial:
74                 PRINTF("%s: Launching Passive Serial Dump\n", __func__);
75                 ret_val = CYC2_ps_dump(desc, buf, bsize);
76                 break;
77
78                 /* Add new interface types here */
79
80         default:
81                 printf("%s: Unsupported interface type, %d\n",
82                        __func__, desc->iface);
83         }
84
85         return ret_val;
86 }
87
88 int CYC2_info(Altera_desc *desc)
89 {
90         return FPGA_SUCCESS;
91 }
92
93 /* ------------------------------------------------------------------------- */
94 /* CYCLON2 Passive Serial Generic Implementation                             */
95 static int CYC2_ps_load(Altera_desc *desc, const void *buf, size_t bsize)
96 {
97         int ret_val = FPGA_FAIL;        /* assume the worst */
98         Altera_CYC2_Passive_Serial_fns *fn = desc->iface_fns;
99         int     ret = 0;
100
101         PRINTF("%s: start with interface functions @ 0x%p\n",
102                __func__, fn);
103
104         if (fn) {
105                 int cookie = desc->cookie;      /* make a local copy */
106                 unsigned long ts;               /* timestamp */
107
108                 PRINTF("%s: Function Table:\n"
109                                 "ptr:\t0x%p\n"
110                                 "struct: 0x%p\n"
111                                 "config:\t0x%p\n"
112                                 "status:\t0x%p\n"
113                                 "write:\t0x%p\n"
114                                 "done:\t0x%p\n\n",
115                                 __func__, &fn, fn, fn->config, fn->status,
116                                 fn->write, fn->done);
117 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
118                 printf("Loading FPGA Device %d...", cookie);
119 #endif
120
121                 /*
122                  * Run the pre configuration function if there is one.
123                  */
124                 if (*fn->pre)
125                         (*fn->pre) (cookie);
126
127                 /* Establish the initial state */
128                 (*fn->config) (false, true, cookie);    /* De-assert nCONFIG */
129                 udelay(100);
130                 (*fn->config) (true, true, cookie);     /* Assert nCONFIG */
131
132                 udelay(2);              /* T_cfg > 2us  */
133
134                 /* Wait for nSTATUS to be asserted */
135                 ts = get_timer(0);              /* get current time */
136                 do {
137                         CONFIG_FPGA_DELAY();
138                         if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) {
139                                 /* check the time */
140                                 puts("** Timeout waiting for STATUS to go high.\n");
141                                 (*fn->abort) (cookie);
142                                 return FPGA_FAIL;
143                         }
144                 } while (!(*fn->status) (cookie));
145
146                 /* Get ready for the burn */
147                 CONFIG_FPGA_DELAY();
148
149                 ret = (*fn->write) (buf, bsize, true, cookie);
150                 if (ret) {
151                         puts("** Write failed.\n");
152                         (*fn->abort) (cookie);
153                         return FPGA_FAIL;
154                 }
155 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
156                 puts(" OK? ...");
157 #endif
158
159                 CONFIG_FPGA_DELAY();
160
161 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
162                 putc(' ');                      /* terminate the dotted line */
163 #endif
164
165                 /*
166                  * Checking FPGA's CONF_DONE signal - correctly booted ?
167                  */
168
169                 if (!(*fn->done) (cookie)) {
170                         puts("** Booting failed! CONF_DONE is still deasserted.\n");
171                         (*fn->abort) (cookie);
172                         return FPGA_FAIL;
173                 }
174 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
175                 puts(" OK\n");
176 #endif
177
178                 ret_val = FPGA_SUCCESS;
179
180 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
181                 if (ret_val == FPGA_SUCCESS)
182                         puts("Done.\n");
183                 else
184                         puts("Fail.\n");
185 #endif
186
187                 /*
188                  * Run the post configuration function if there is one.
189                  */
190                 if (*fn->post)
191                         (*fn->post) (cookie);
192         } else {
193                 printf("%s: NULL Interface function table!\n", __func__);
194         }
195
196         return ret_val;
197 }
198
199 static int CYC2_ps_dump(Altera_desc *desc, const void *buf, size_t bsize)
200 {
201         /* Readback is only available through the Slave Parallel and         */
202         /* boundary-scan interfaces.                                         */
203         printf("%s: Passive Serial Dumping is unavailable\n", __func__);
204         return FPGA_FAIL;
205 }