Commit 3372081cfd25e2afaaa043d9da78f7de1cf84636
Committed by
Michal Simek
1 parent
25d63a3677
Exists in
smarc_8mq_lf_v2020.04
and in
9 other branches
fpga: virtex2: Split out image writing from pre/post operations
This is in preparation for adding slave serial programming support, which uses the same pre/post operations as slave SelectMAP, to avoid duplicating code. Signed-off-by: Robert Hancock <hancock@sedsystems.ca> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Showing 1 changed file with 174 additions and 157 deletions Side-by-side Diff
drivers/fpga/virtex2.c
... | ... | @@ -154,202 +154,219 @@ |
154 | 154 | * INIT_B and DONE lines. If both are high, configuration has |
155 | 155 | * succeeded. Congratulations! |
156 | 156 | */ |
157 | -static int virtex2_ssm_load(xilinx_desc *desc, const void *buf, size_t bsize) | |
157 | +static int virtex2_slave_pre(xilinx_virtex2_slave_selectmap_fns *fn, int cookie) | |
158 | 158 | { |
159 | - int ret_val = FPGA_FAIL; | |
160 | - xilinx_virtex2_slave_selectmap_fns *fn = desc->iface_fns; | |
159 | + unsigned long ts; | |
161 | 160 | |
162 | 161 | PRINTF("%s:%d: Start with interface functions @ 0x%p\n", |
163 | 162 | __func__, __LINE__, fn); |
164 | 163 | |
165 | - if (fn) { | |
166 | - size_t bytecount = 0; | |
167 | - unsigned char *data = (unsigned char *)buf; | |
168 | - int cookie = desc->cookie; | |
169 | - unsigned long ts; | |
164 | + if (!fn) { | |
165 | + printf("%s:%d: NULL Interface function table!\n", | |
166 | + __func__, __LINE__); | |
167 | + return FPGA_FAIL; | |
168 | + } | |
170 | 169 | |
171 | - /* Gotta split this one up (so the stack won't blow??) */ | |
172 | - PRINTF("%s:%d: Function Table:\n" | |
173 | - " base 0x%p\n" | |
174 | - " struct 0x%p\n" | |
175 | - " pre 0x%p\n" | |
176 | - " prog 0x%p\n" | |
177 | - " init 0x%p\n" | |
178 | - " error 0x%p\n", | |
179 | - __func__, __LINE__, | |
180 | - &fn, fn, fn->pre, fn->pgm, fn->init, fn->err); | |
181 | - PRINTF(" clock 0x%p\n" | |
182 | - " cs 0x%p\n" | |
183 | - " write 0x%p\n" | |
184 | - " rdata 0x%p\n" | |
185 | - " wdata 0x%p\n" | |
186 | - " busy 0x%p\n" | |
187 | - " abort 0x%p\n" | |
188 | - " post 0x%p\n\n", | |
189 | - fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, | |
190 | - fn->busy, fn->abort, fn->post); | |
170 | + /* Gotta split this one up (so the stack won't blow??) */ | |
171 | + PRINTF("%s:%d: Function Table:\n" | |
172 | + " base 0x%p\n" | |
173 | + " struct 0x%p\n" | |
174 | + " pre 0x%p\n" | |
175 | + " prog 0x%p\n" | |
176 | + " init 0x%p\n" | |
177 | + " error 0x%p\n", | |
178 | + __func__, __LINE__, | |
179 | + &fn, fn, fn->pre, fn->pgm, fn->init, fn->err); | |
180 | + PRINTF(" clock 0x%p\n" | |
181 | + " cs 0x%p\n" | |
182 | + " write 0x%p\n" | |
183 | + " rdata 0x%p\n" | |
184 | + " wdata 0x%p\n" | |
185 | + " busy 0x%p\n" | |
186 | + " abort 0x%p\n" | |
187 | + " post 0x%p\n\n", | |
188 | + fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, | |
189 | + fn->busy, fn->abort, fn->post); | |
191 | 190 | |
192 | 191 | #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK |
193 | - printf("Initializing FPGA Device %d...\n", cookie); | |
192 | + printf("Initializing FPGA Device %d...\n", cookie); | |
194 | 193 | #endif |
195 | - /* | |
196 | - * Run the pre configuration function if there is one. | |
197 | - */ | |
198 | - if (*fn->pre) | |
199 | - (*fn->pre)(cookie); | |
194 | + /* | |
195 | + * Run the pre configuration function if there is one. | |
196 | + */ | |
197 | + if (*fn->pre) | |
198 | + (*fn->pre)(cookie); | |
200 | 199 | |
201 | - /* | |
202 | - * Assert the program line. The minimum pulse width for | |
203 | - * Virtex II devices is 300 nS (Tprogram parameter in | |
204 | - * datasheet). There is no maximum value for the pulse width. | |
205 | - * Check to make sure that INIT_B goes low after assertion of | |
206 | - * PROG_B | |
207 | - */ | |
208 | - (*fn->pgm)(true, true, cookie); | |
209 | - udelay(10); | |
210 | - ts = get_timer(0); | |
211 | - do { | |
212 | - if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_INIT) { | |
213 | - printf("%s:%d: ** Timeout after %d ticks waiting for INIT to assert.\n", | |
214 | - __func__, __LINE__, | |
215 | - CONFIG_SYS_FPGA_WAIT_INIT); | |
216 | - (*fn->abort)(cookie); | |
217 | - return FPGA_FAIL; | |
218 | - } | |
219 | - } while (!(*fn->init)(cookie)); | |
200 | + /* | |
201 | + * Assert the program line. The minimum pulse width for | |
202 | + * Virtex II devices is 300 nS (Tprogram parameter in datasheet). | |
203 | + * There is no maximum value for the pulse width. Check to make | |
204 | + * sure that INIT_B goes low after assertion of PROG_B | |
205 | + */ | |
206 | + (*fn->pgm)(true, true, cookie); | |
207 | + udelay(10); | |
208 | + ts = get_timer(0); | |
209 | + do { | |
210 | + if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_INIT) { | |
211 | + printf("%s:%d: ** Timeout after %d ticks waiting for INIT to assert.\n", | |
212 | + __func__, __LINE__, CONFIG_SYS_FPGA_WAIT_INIT); | |
213 | + (*fn->abort)(cookie); | |
214 | + return FPGA_FAIL; | |
215 | + } | |
216 | + } while (!(*fn->init)(cookie)); | |
220 | 217 | |
221 | - (*fn->pgm)(false, true, cookie); | |
222 | - CONFIG_FPGA_DELAY(); | |
218 | + (*fn->pgm)(false, true, cookie); | |
219 | + CONFIG_FPGA_DELAY(); | |
220 | + if (fn->clk) | |
223 | 221 | (*fn->clk)(true, true, cookie); |
224 | 222 | |
225 | - /* | |
226 | - * Start a timer and wait for INIT_B to go high | |
227 | - */ | |
228 | - ts = get_timer(0); | |
229 | - do { | |
230 | - CONFIG_FPGA_DELAY(); | |
231 | - if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_INIT) { | |
232 | - printf("%s:%d: ** Timeout after %d ticks waiting for INIT to deassert.\n", | |
233 | - __func__, __LINE__, | |
234 | - CONFIG_SYS_FPGA_WAIT_INIT); | |
235 | - (*fn->abort)(cookie); | |
236 | - return FPGA_FAIL; | |
237 | - } | |
238 | - } while ((*fn->init)(cookie) && (*fn->busy)(cookie)); | |
223 | + /* | |
224 | + * Start a timer and wait for INIT_B to go high | |
225 | + */ | |
226 | + ts = get_timer(0); | |
227 | + do { | |
228 | + CONFIG_FPGA_DELAY(); | |
229 | + if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_INIT) { | |
230 | + printf("%s:%d: ** Timeout after %d ticks waiting for INIT to deassert.\n", | |
231 | + __func__, __LINE__, CONFIG_SYS_FPGA_WAIT_INIT); | |
232 | + (*fn->abort)(cookie); | |
233 | + return FPGA_FAIL; | |
234 | + } | |
235 | + } while ((*fn->init)(cookie) && (*fn->busy)(cookie)); | |
239 | 236 | |
237 | + if (fn->wr) | |
240 | 238 | (*fn->wr)(true, true, cookie); |
239 | + if (fn->cs) | |
241 | 240 | (*fn->cs)(true, true, cookie); |
242 | 241 | |
243 | - mdelay(10); | |
242 | + mdelay(10); | |
243 | + return FPGA_SUCCESS; | |
244 | +} | |
244 | 245 | |
245 | - /* | |
246 | - * Load the data byte by byte | |
247 | - */ | |
248 | - while (bytecount < bsize) { | |
249 | -#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC | |
250 | - if (ctrlc()) { | |
251 | - (*fn->abort)(cookie); | |
252 | - return FPGA_FAIL; | |
253 | - } | |
246 | +static int virtex2_slave_post(xilinx_virtex2_slave_selectmap_fns *fn, | |
247 | + int cookie) | |
248 | +{ | |
249 | + int ret_val = FPGA_SUCCESS; | |
250 | + unsigned long ts; | |
251 | + | |
252 | + /* | |
253 | + * Finished writing the data; deassert FPGA CS_B and WRITE_B signals. | |
254 | + */ | |
255 | + CONFIG_FPGA_DELAY(); | |
256 | + if (fn->cs) | |
257 | + (*fn->cs)(false, true, cookie); | |
258 | + if (fn->wr) | |
259 | + (*fn->wr)(false, true, cookie); | |
260 | + | |
261 | +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK | |
262 | + putc('\n'); | |
254 | 263 | #endif |
255 | 264 | |
256 | - if ((*fn->done)(cookie) == FPGA_SUCCESS) { | |
257 | - PRINTF("%s:%d:done went active early, bytecount = %d\n", | |
258 | - __func__, __LINE__, bytecount); | |
259 | - break; | |
260 | - } | |
265 | + /* | |
266 | + * Check for successful configuration. FPGA INIT_B and DONE | |
267 | + * should both be high upon successful configuration. | |
268 | + */ | |
269 | + ts = get_timer(0); | |
270 | + ret_val = FPGA_SUCCESS; | |
271 | + while (((*fn->done)(cookie) == FPGA_FAIL) || | |
272 | + (*fn->init)(cookie)) { | |
273 | + if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_CONFIG) { | |
274 | + printf("%s:%d: ** Timeout after %d ticks waiting for DONE to assert and INIT to deassert\n", | |
275 | + __func__, __LINE__, CONFIG_SYS_FPGA_WAIT_CONFIG); | |
276 | + (*fn->abort)(cookie); | |
277 | + ret_val = FPGA_FAIL; | |
278 | + break; | |
279 | + } | |
280 | + } | |
261 | 281 | |
262 | -#ifdef CONFIG_SYS_FPGA_CHECK_ERROR | |
263 | - if ((*fn->init)(cookie)) { | |
264 | - printf("\n%s:%d: ** Error: INIT asserted during configuration\n", | |
265 | - __func__, __LINE__); | |
266 | - printf("%d = buffer offset, %d = buffer size\n", | |
267 | - bytecount, bsize); | |
268 | - (*fn->abort)(cookie); | |
269 | - return FPGA_FAIL; | |
270 | - } | |
282 | + if (ret_val == FPGA_SUCCESS) { | |
283 | +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK | |
284 | + printf("Initialization of FPGA device %d complete\n", cookie); | |
271 | 285 | #endif |
286 | + /* | |
287 | + * Run the post configuration function if there is one. | |
288 | + */ | |
289 | + if (*fn->post) | |
290 | + (*fn->post)(cookie); | |
291 | + } else { | |
292 | +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK | |
293 | + printf("** Initialization of FPGA device %d FAILED\n", | |
294 | + cookie); | |
295 | +#endif | |
296 | + } | |
297 | + return ret_val; | |
298 | +} | |
272 | 299 | |
273 | - (*fn->wdata)(data[bytecount++], true, cookie); | |
274 | - CONFIG_FPGA_DELAY(); | |
300 | +static int virtex2_ssm_load(xilinx_desc *desc, const void *buf, size_t bsize) | |
301 | +{ | |
302 | + int ret_val = FPGA_FAIL; | |
303 | + xilinx_virtex2_slave_selectmap_fns *fn = desc->iface_fns; | |
304 | + size_t bytecount = 0; | |
305 | + unsigned char *data = (unsigned char *)buf; | |
306 | + int cookie = desc->cookie; | |
275 | 307 | |
276 | - /* | |
277 | - * Cycle the clock pin | |
278 | - */ | |
279 | - (*fn->clk)(false, true, cookie); | |
280 | - CONFIG_FPGA_DELAY(); | |
281 | - (*fn->clk)(true, true, cookie); | |
308 | + ret_val = virtex2_slave_pre(fn, cookie); | |
309 | + if (ret_val != FPGA_SUCCESS) | |
310 | + return ret_val; | |
282 | 311 | |
283 | -#ifdef CONFIG_SYS_FPGA_CHECK_BUSY | |
284 | - ts = get_timer(0); | |
285 | - while ((*fn->busy)(cookie)) { | |
286 | - if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_BUSY) { | |
287 | - printf("%s:%d: ** Timeout after %d ticks waiting for BUSY to deassert\n", | |
288 | - __func__, __LINE__, | |
289 | - CONFIG_SYS_FPGA_WAIT_BUSY); | |
290 | - (*fn->abort)(cookie); | |
291 | - return FPGA_FAIL; | |
292 | - } | |
293 | - } | |
312 | + /* | |
313 | + * Load the data byte by byte | |
314 | + */ | |
315 | + while (bytecount < bsize) { | |
316 | +#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC | |
317 | + if (ctrlc()) { | |
318 | + (*fn->abort)(cookie); | |
319 | + return FPGA_FAIL; | |
320 | + } | |
294 | 321 | #endif |
295 | 322 | |
296 | -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK | |
297 | - if (bytecount % (bsize / 40) == 0) | |
298 | - putc('.'); | |
299 | -#endif | |
323 | + if ((*fn->done)(cookie) == FPGA_SUCCESS) { | |
324 | + PRINTF("%s:%d:done went active early, bytecount = %d\n", | |
325 | + __func__, __LINE__, bytecount); | |
326 | + break; | |
300 | 327 | } |
301 | 328 | |
302 | - /* | |
303 | - * Finished writing the data; deassert FPGA CS_B and WRITE_B | |
304 | - * signals. | |
305 | - */ | |
306 | - CONFIG_FPGA_DELAY(); | |
307 | - (*fn->cs)(false, true, cookie); | |
308 | - (*fn->wr)(false, true, cookie); | |
309 | - | |
310 | -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK | |
311 | - putc('\n'); | |
329 | +#ifdef CONFIG_SYS_FPGA_CHECK_ERROR | |
330 | + if ((*fn->init)(cookie)) { | |
331 | + printf("\n%s:%d: ** Error: INIT asserted during configuration\n", | |
332 | + __func__, __LINE__); | |
333 | + printf("%zu = buffer offset, %zu = buffer size\n", | |
334 | + bytecount, bsize); | |
335 | + (*fn->abort)(cookie); | |
336 | + return FPGA_FAIL; | |
337 | + } | |
312 | 338 | #endif |
313 | 339 | |
340 | + (*fn->wdata)(data[bytecount++], true, cookie); | |
341 | + CONFIG_FPGA_DELAY(); | |
342 | + | |
314 | 343 | /* |
315 | - * Check for successful configuration. FPGA INIT_B and DONE | |
316 | - * should both be high upon successful configuration. | |
344 | + * Cycle the clock pin | |
317 | 345 | */ |
346 | + (*fn->clk)(false, true, cookie); | |
347 | + CONFIG_FPGA_DELAY(); | |
348 | + (*fn->clk)(true, true, cookie); | |
349 | + | |
350 | +#ifdef CONFIG_SYS_FPGA_CHECK_BUSY | |
318 | 351 | ts = get_timer(0); |
319 | - ret_val = FPGA_SUCCESS; | |
320 | - while (((*fn->done)(cookie) == FPGA_FAIL) || | |
321 | - (*fn->init)(cookie)) { | |
322 | - if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_CONFIG) { | |
323 | - printf("%s:%d: ** Timeout after %d ticks waiting for DONE toassert and INIT to deassert\n", | |
352 | + while ((*fn->busy)(cookie)) { | |
353 | + if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_BUSY) { | |
354 | + printf("%s:%d: ** Timeout after %d ticks waiting for BUSY to deassert\n", | |
324 | 355 | __func__, __LINE__, |
325 | - CONFIG_SYS_FPGA_WAIT_CONFIG); | |
356 | + CONFIG_SYS_FPGA_WAIT_BUSY); | |
326 | 357 | (*fn->abort)(cookie); |
327 | - ret_val = FPGA_FAIL; | |
328 | - break; | |
358 | + return FPGA_FAIL; | |
329 | 359 | } |
330 | 360 | } |
361 | +#endif | |
331 | 362 | |
332 | - if (ret_val == FPGA_SUCCESS) { | |
333 | 363 | #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK |
334 | - printf("Initialization of FPGA device %d complete\n", | |
335 | - cookie); | |
364 | + if (bytecount % (bsize / 40) == 0) | |
365 | + putc('.'); | |
336 | 366 | #endif |
337 | - /* | |
338 | - * Run the post configuration function if there is one. | |
339 | - */ | |
340 | - if (*fn->post) | |
341 | - (*fn->post)(cookie); | |
342 | - } else { | |
343 | -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK | |
344 | - printf("** Initialization of FPGA device %d FAILED\n", | |
345 | - cookie); | |
346 | -#endif | |
347 | - } | |
348 | - } else { | |
349 | - printf("%s:%d: NULL Interface function table!\n", | |
350 | - __func__, __LINE__); | |
351 | 367 | } |
352 | - return ret_val; | |
368 | + | |
369 | + return virtex2_slave_post(fn, cookie); | |
353 | 370 | } |
354 | 371 | |
355 | 372 | /* |