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