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