1 // SPDX-License-Identifier: GPL-2.0+
4 * Heiko Schocher, hs@denx.de
8 #define LOG_CATEGORY UCLASS_FPGA
10 #include <common.h> /* core U-Boot definitions */
13 #include <ACEX1K.h> /* ACEX device family */
14 #include <linux/delay.h>
16 /* Note: The assumption is that we cannot possibly run fast enough to
17 * overrun the device (the Slave Parallel mode can free run at 50MHz).
18 * If there is a need to operate slower, define CFG_FPGA_DELAY in
19 * the board config file to slow things down.
21 #ifndef CFG_FPGA_DELAY
22 #define CFG_FPGA_DELAY()
25 #ifndef CFG_SYS_FPGA_WAIT
26 #define CFG_SYS_FPGA_WAIT CONFIG_SYS_HZ / 10 /* 100 ms */
29 static int CYC2_ps_load(Altera_desc *desc, const void *buf, size_t bsize);
30 static int CYC2_ps_dump(Altera_desc *desc, const void *buf, size_t bsize);
31 /* static int CYC2_ps_info( Altera_desc *desc ); */
33 /* ------------------------------------------------------------------------- */
34 /* CYCLON2 Generic Implementation */
35 int CYC2_load(Altera_desc *desc, const void *buf, size_t bsize)
37 int ret_val = FPGA_FAIL;
39 switch (desc->iface) {
41 log_debug("Launching Passive Serial Loader\n");
42 ret_val = CYC2_ps_load(desc, buf, bsize);
45 case fast_passive_parallel:
46 /* Fast Passive Parallel (FPP) and PS only differ in what is
47 * done in the write() callback. Use the existing PS load
48 * function for FPP, too.
50 log_debug("Launching Fast Passive Parallel Loader\n");
51 ret_val = CYC2_ps_load(desc, buf, bsize);
54 /* Add new interface types here */
57 printf("%s: Unsupported interface type, %d\n",
58 __func__, desc->iface);
64 int CYC2_dump(Altera_desc *desc, const void *buf, size_t bsize)
66 int ret_val = FPGA_FAIL;
68 switch (desc->iface) {
70 log_debug("Launching Passive Serial Dump\n");
71 ret_val = CYC2_ps_dump(desc, buf, bsize);
74 /* Add new interface types here */
77 printf("%s: Unsupported interface type, %d\n",
78 __func__, desc->iface);
84 int CYC2_info(Altera_desc *desc)
89 /* ------------------------------------------------------------------------- */
90 /* CYCLON2 Passive Serial Generic Implementation */
91 static int CYC2_ps_load(Altera_desc *desc, const void *buf, size_t bsize)
93 int ret_val = FPGA_FAIL; /* assume the worst */
94 Altera_CYC2_Passive_Serial_fns *fn = desc->iface_fns;
97 log_debug("start with interface functions @ 0x%p\n", fn);
100 int cookie = desc->cookie; /* make a local copy */
101 unsigned long ts; /* timestamp */
103 log_debug("Function Table:\n"
110 &fn, fn, fn->config, fn->status,
111 fn->write, fn->done);
112 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
113 printf("Loading FPGA Device %d...", cookie);
117 * Run the pre configuration function if there is one.
122 /* Establish the initial state */
123 (*fn->config) (false, true, cookie); /* De-assert nCONFIG */
125 (*fn->config) (true, true, cookie); /* Assert nCONFIG */
127 udelay(2); /* T_cfg > 2us */
129 /* Wait for nSTATUS to be asserted */
130 ts = get_timer(0); /* get current time */
133 if (get_timer(ts) > CFG_SYS_FPGA_WAIT) {
135 puts("** Timeout waiting for STATUS to go high.\n");
136 (*fn->abort) (cookie);
139 } while (!(*fn->status) (cookie));
141 /* Get ready for the burn */
144 ret = (*fn->write) (buf, bsize, true, cookie);
146 puts("** Write failed.\n");
147 (*fn->abort) (cookie);
150 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
156 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
157 putc(' '); /* terminate the dotted line */
161 * Checking FPGA's CONF_DONE signal - correctly booted ?
164 if (!(*fn->done) (cookie)) {
165 puts("** Booting failed! CONF_DONE is still deasserted.\n");
166 (*fn->abort) (cookie);
169 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
173 ret_val = FPGA_SUCCESS;
175 #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
176 if (ret_val == FPGA_SUCCESS)
183 * Run the post configuration function if there is one.
186 (*fn->post) (cookie);
188 printf("%s: NULL Interface function table!\n", __func__);
194 static int CYC2_ps_dump(Altera_desc *desc, const void *buf, size_t bsize)
196 /* Readback is only available through the Slave Parallel and */
197 /* boundary-scan interfaces. */
198 printf("%s: Passive Serial Dumping is unavailable\n", __func__);