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 */
CYC2_load(Altera_desc * desc,const void * buf,size_t bsize)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", __FUNCTION__);
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 __FUNCTION__);
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 __FUNCTION__, desc->iface);
63 }
64
65 return ret_val;
66 }
67
CYC2_dump(Altera_desc * desc,const void * buf,size_t bsize)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", __FUNCTION__);
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 __FUNCTION__, desc->iface);
83 }
84
85 return ret_val;
86 }
87
CYC2_info(Altera_desc * desc)88 int CYC2_info( Altera_desc *desc )
89 {
90 return FPGA_SUCCESS;
91 }
92
93 /* ------------------------------------------------------------------------- */
94 /* CYCLON2 Passive Serial Generic Implementation */
CYC2_ps_load(Altera_desc * desc,const void * buf,size_t bsize)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 __FUNCTION__, 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 __FUNCTION__, &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
128 /* Establish the initial state */
129 (*fn->config) (false, true, cookie); /* De-assert nCONFIG */
130 udelay(100);
131 (*fn->config) (true, true, cookie); /* Assert nCONFIG */
132
133 udelay(2); /* T_cfg > 2us */
134
135 /* Wait for nSTATUS to be asserted */
136 ts = get_timer (0); /* get current time */
137 do {
138 CONFIG_FPGA_DELAY ();
139 if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* 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 }
184 else {
185 puts ("Fail.\n");
186 }
187 #endif
188 (*fn->post) (cookie);
189
190 } else {
191 printf ("%s: NULL Interface function table!\n", __FUNCTION__);
192 }
193
194 return ret_val;
195 }
196
CYC2_ps_dump(Altera_desc * desc,const void * buf,size_t bsize)197 static int CYC2_ps_dump(Altera_desc *desc, const void *buf, size_t bsize)
198 {
199 /* Readback is only available through the Slave Parallel and */
200 /* boundary-scan interfaces. */
201 printf ("%s: Passive Serial Dumping is unavailable\n",
202 __FUNCTION__);
203 return FPGA_FAIL;
204 }
205