Commit 3372081cfd25e2afaaa043d9da78f7de1cf84636

Authored by Robert Hancock
Committed by Michal Simek
1 parent 25d63a3677

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 /*