8b1620b1b2d0b0f614004726a3814155d039c543
[linux-3.10.git] / drivers / staging / altera-stapl / altera-jtag.c
1 /*
2  * altera-jtag.c
3  *
4  * altera FPGA driver
5  *
6  * Copyright (C) Altera Corporation 1998-2001
7  * Copyright (C) 2010 NetUP Inc.
8  * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  */
25
26 #include <linux/delay.h>
27 #include <linux/firmware.h>
28 #include <linux/slab.h>
29 #include "altera.h"
30 #include "altera-exprt.h"
31 #include "altera-jtag.h"
32
33 #define alt_jtag_io(a, b, c)\
34                 astate->config->jtag_io(astate->config->dev, a, b, c);
35
36 #define alt_malloc(a)   kzalloc(a, GFP_KERNEL);
37
38 /*
39  * This structure shows, for each JTAG state, which state is reached after
40  * a single TCK clock cycle with TMS high or TMS low, respectively.  This
41  * describes all possible state transitions in the JTAG state machine.
42  */
43 struct altera_jtag_machine {
44         enum altera_jtag_state tms_high;
45         enum altera_jtag_state tms_low;
46 };
47
48 static const struct altera_jtag_machine altera_transitions[] = {
49         /* RESET     */ { RESET,        IDLE },
50         /* IDLE      */ { DRSELECT,     IDLE },
51         /* DRSELECT  */ { IRSELECT,     DRCAPTURE },
52         /* DRCAPTURE */ { DREXIT1,      DRSHIFT },
53         /* DRSHIFT   */ { DREXIT1,      DRSHIFT },
54         /* DREXIT1   */ { DRUPDATE,     DRPAUSE },
55         /* DRPAUSE   */ { DREXIT2,      DRPAUSE },
56         /* DREXIT2   */ { DRUPDATE,     DRSHIFT },
57         /* DRUPDATE  */ { DRSELECT,     IDLE },
58         /* IRSELECT  */ { RESET,        IRCAPTURE },
59         /* IRCAPTURE */ { IREXIT1,      IRSHIFT },
60         /* IRSHIFT   */ { IREXIT1,      IRSHIFT },
61         /* IREXIT1   */ { IRUPDATE,     IRPAUSE },
62         /* IRPAUSE   */ { IREXIT2,      IRPAUSE },
63         /* IREXIT2   */ { IRUPDATE,     IRSHIFT },
64         /* IRUPDATE  */ { DRSELECT,     IDLE }
65 };
66
67 /*
68  * This table contains the TMS value to be used to take the NEXT STEP on
69  * the path to the desired state.  The array index is the current state,
70  * and the bit position is the desired endstate.  To find out which state
71  * is used as the intermediate state, look up the TMS value in the
72  * altera_transitions[] table.
73  */
74 static const u16 altera_jtag_path_map[16] = {
75         /* RST  RTI     SDRS    CDR     SDR     E1DR    PDR     E2DR */
76         0x0001, 0xFFFD, 0xFE01, 0xFFE7, 0xFFEF, 0xFF0F, 0xFFBF, 0xFFFF,
77         /* UDR  SIRS    CIR     SIR     E1IR    PIR     E2IR    UIR */
78         0xFEFD, 0x0001, 0xF3FF, 0xF7FF, 0x87FF, 0xDFFF, 0xFFFF, 0x7FFD
79 };
80
81 /* Flag bits for alt_jtag_io() function */
82 #define TMS_HIGH   1
83 #define TMS_LOW    0
84 #define TDI_HIGH   1
85 #define TDI_LOW    0
86 #define READ_TDO   1
87 #define IGNORE_TDO 0
88
89 int altera_jinit(struct altera_state *astate)
90 {
91         struct altera_jtag *js = &astate->js;
92
93         /* initial JTAG state is unknown */
94         js->jtag_state = ILLEGAL_JTAG_STATE;
95
96         /* initialize to default state */
97         js->drstop_state = IDLE;
98         js->irstop_state = IDLE;
99         js->dr_pre  = 0;
100         js->dr_post = 0;
101         js->ir_pre  = 0;
102         js->ir_post = 0;
103         js->dr_length    = 0;
104         js->ir_length    = 0;
105
106         js->dr_pre_data  = NULL;
107         js->dr_post_data = NULL;
108         js->ir_pre_data  = NULL;
109         js->ir_post_data = NULL;
110         js->dr_buffer    = NULL;
111         js->ir_buffer    = NULL;
112
113         return 0;
114 }
115
116 int altera_set_drstop(struct altera_jtag *js, enum altera_jtag_state state)
117 {
118         js->drstop_state = state;
119
120         return 0;
121 }
122
123 int altera_set_irstop(struct altera_jtag *js, enum altera_jtag_state state)
124 {
125         js->irstop_state = state;
126
127         return 0;
128 }
129
130 int altera_set_dr_pre(struct altera_jtag *js,
131                                 u32 count, u32 start_index,
132                                 u8 *preamble_data)
133 {
134         int status = 0;
135         u32 i;
136         u32 j;
137
138         if (count > js->dr_pre) {
139                 kfree(js->dr_pre_data);
140                 js->dr_pre_data = (u8 *)alt_malloc((count + 7) >> 3);
141                 if (js->dr_pre_data == NULL)
142                         status = -ENOMEM;
143                 else
144                         js->dr_pre = count;
145         } else
146                 js->dr_pre = count;
147
148         if (status == 0) {
149                 for (i = 0; i < count; ++i) {
150                         j = i + start_index;
151
152                         if (preamble_data == NULL)
153                                 js->dr_pre_data[i >> 3] |= (1 << (i & 7));
154                         else {
155                                 if (preamble_data[j >> 3] & (1 << (j & 7)))
156                                         js->dr_pre_data[i >> 3] |=
157                                                         (1 << (i & 7));
158                                 else
159                                         js->dr_pre_data[i >> 3] &=
160                                                         ~(u32)(1 << (i & 7));
161
162                         }
163                 }
164         }
165
166         return status;
167 }
168
169 int altera_set_ir_pre(struct altera_jtag *js, u32 count, u32 start_index,
170                                                         u8 *preamble_data)
171 {
172         int status = 0;
173         u32 i;
174         u32 j;
175
176         if (count > js->ir_pre) {
177                 kfree(js->ir_pre_data);
178                 js->ir_pre_data = (u8 *)alt_malloc((count + 7) >> 3);
179                 if (js->ir_pre_data == NULL)
180                         status = -ENOMEM;
181                 else
182                         js->ir_pre = count;
183
184         } else
185                 js->ir_pre = count;
186
187         if (status == 0) {
188                 for (i = 0; i < count; ++i) {
189                         j = i + start_index;
190                         if (preamble_data == NULL)
191                                 js->ir_pre_data[i >> 3] |= (1 << (i & 7));
192                         else {
193                                 if (preamble_data[j >> 3] & (1 << (j & 7)))
194                                         js->ir_pre_data[i >> 3] |=
195                                                         (1 << (i & 7));
196                                 else
197                                         js->ir_pre_data[i >> 3] &=
198                                                         ~(u32)(1 << (i & 7));
199
200                         }
201                 }
202         }
203
204         return status;
205 }
206
207 int altera_set_dr_post(struct altera_jtag *js, u32 count, u32 start_index,
208                                                 u8 *postamble_data)
209 {
210         int status = 0;
211         u32 i;
212         u32 j;
213
214         if (count > js->dr_post) {
215                 kfree(js->dr_post_data);
216                 js->dr_post_data = (u8 *)alt_malloc((count + 7) >> 3);
217
218                 if (js->dr_post_data == NULL)
219                         status = -ENOMEM;
220                 else
221                         js->dr_post = count;
222
223         } else
224                 js->dr_post = count;
225
226         if (status == 0) {
227                 for (i = 0; i < count; ++i) {
228                         j = i + start_index;
229
230                         if (postamble_data == NULL)
231                                 js->dr_post_data[i >> 3] |= (1 << (i & 7));
232                         else {
233                                 if (postamble_data[j >> 3] & (1 << (j & 7)))
234                                         js->dr_post_data[i >> 3] |=
235                                                                 (1 << (i & 7));
236                                 else
237                                         js->dr_post_data[i >> 3] &=
238                                             ~(u32)(1 << (i & 7));
239
240                         }
241                 }
242         }
243
244         return status;
245 }
246
247 int altera_set_ir_post(struct altera_jtag *js, u32 count, u32 start_index,
248                                                 u8 *postamble_data)
249 {
250         int status = 0;
251         u32 i;
252         u32 j;
253
254         if (count > js->ir_post) {
255                 kfree(js->ir_post_data);
256                 js->ir_post_data = (u8 *)alt_malloc((count + 7) >> 3);
257                 if (js->ir_post_data == NULL)
258                         status = -ENOMEM;
259                 else
260                         js->ir_post = count;
261
262         } else
263                 js->ir_post = count;
264
265         if (status != 0)
266                 return status;
267
268         for (i = 0; i < count; ++i) {
269                 j = i + start_index;
270
271                 if (postamble_data == NULL)
272                         js->ir_post_data[i >> 3] |= (1 << (i & 7));
273                 else {
274                         if (postamble_data[j >> 3] & (1 << (j & 7)))
275                                 js->ir_post_data[i >> 3] |= (1 << (i & 7));
276                         else
277                                 js->ir_post_data[i >> 3] &=
278                                     ~(u32)(1 << (i & 7));
279
280                 }
281         }
282
283         return status;
284 }
285
286 static void altera_jreset_idle(struct altera_state *astate)
287 {
288         struct altera_jtag *js = &astate->js;
289         int i;
290         /* Go to Test Logic Reset (no matter what the starting state may be) */
291         for (i = 0; i < 5; ++i)
292                 alt_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);
293
294         /* Now step to Run Test / Idle */
295         alt_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
296         js->jtag_state = IDLE;
297 }
298
299 int altera_goto_jstate(struct altera_state *astate,
300                                         enum altera_jtag_state state)
301 {
302         struct altera_jtag *js = &astate->js;
303         int tms;
304         int count = 0;
305         int status = 0;
306
307         if (js->jtag_state == ILLEGAL_JTAG_STATE)
308                 /* initialize JTAG chain to known state */
309                 altera_jreset_idle(astate);
310
311         if (js->jtag_state == state) {
312                 /*
313                  * We are already in the desired state.
314                  * If it is a stable state, loop here.
315                  * Otherwise do nothing (no clock cycles).
316                  */
317                 if ((state == IDLE) || (state == DRSHIFT) ||
318                         (state == DRPAUSE) || (state == IRSHIFT) ||
319                                 (state == IRPAUSE)) {
320                         alt_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
321                 } else if (state == RESET)
322                         alt_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);
323
324         } else {
325                 while ((js->jtag_state != state) && (count < 9)) {
326                         /* Get TMS value to take a step toward desired state */
327                         tms = (altera_jtag_path_map[js->jtag_state] &
328                                                         (1 << state))
329                                                         ? TMS_HIGH : TMS_LOW;
330
331                         /* Take a step */
332                         alt_jtag_io(tms, TDI_LOW, IGNORE_TDO);
333
334                         if (tms)
335                                 js->jtag_state =
336                                         altera_transitions[js->jtag_state].tms_high;
337                         else
338                                 js->jtag_state =
339                                         altera_transitions[js->jtag_state].tms_low;
340
341                         ++count;
342                 }
343         }
344
345         if (js->jtag_state != state)
346                 status = -EREMOTEIO;
347
348         return status;
349 }
350
351 int altera_wait_cycles(struct altera_state *astate,
352                                         s32 cycles,
353                                         enum altera_jtag_state wait_state)
354 {
355         struct altera_jtag *js = &astate->js;
356         int tms;
357         s32 count;
358         int status = 0;
359
360         if (js->jtag_state != wait_state)
361                 status = altera_goto_jstate(astate, wait_state);
362
363         if (status == 0) {
364                 /*
365                  * Set TMS high to loop in RESET state
366                  * Set TMS low to loop in any other stable state
367                  */
368                 tms = (wait_state == RESET) ? TMS_HIGH : TMS_LOW;
369
370                 for (count = 0L; count < cycles; count++)
371                         alt_jtag_io(tms, TDI_LOW, IGNORE_TDO);
372
373         }
374
375         return status;
376 }
377
378 int altera_wait_msecs(struct altera_state *astate,
379                         s32 microseconds, enum altera_jtag_state wait_state)
380 /*
381  * Causes JTAG hardware to sit in the specified stable
382  * state for the specified duration of real time.  If
383  * no JTAG operations have been performed yet, then only
384  * a delay is performed.  This permits the WAIT USECS
385  * statement to be used in VECTOR programs without causing
386  * any JTAG operations.
387  * Returns 0 for success, else appropriate error code.
388  */
389 {
390         struct altera_jtag *js = &astate->js;
391         int status = 0;
392
393         if ((js->jtag_state != ILLEGAL_JTAG_STATE) &&
394             (js->jtag_state != wait_state))
395                 status = altera_goto_jstate(astate, wait_state);
396
397         if (status == 0)
398                 /* Wait for specified time interval */
399                 udelay(microseconds);
400
401         return status;
402 }
403
404 static void altera_concatenate_data(u8 *buffer,
405                                 u8 *preamble_data,
406                                 u32 preamble_count,
407                                 u8 *target_data,
408                                 u32 start_index,
409                                 u32 target_count,
410                                 u8 *postamble_data,
411                                 u32 postamble_count)
412 /*
413  * Copies preamble data, target data, and postamble data
414  * into one buffer for IR or DR scans.
415  */
416 {
417         u32 i, j, k;
418
419         for (i = 0L; i < preamble_count; ++i) {
420                 if (preamble_data[i >> 3L] & (1L << (i & 7L)))
421                         buffer[i >> 3L] |= (1L << (i & 7L));
422                 else
423                         buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));
424
425         }
426
427         j = start_index;
428         k = preamble_count + target_count;
429         for (; i < k; ++i, ++j) {
430                 if (target_data[j >> 3L] & (1L << (j & 7L)))
431                         buffer[i >> 3L] |= (1L << (i & 7L));
432                 else
433                         buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));
434
435         }
436
437         j = 0L;
438         k = preamble_count + target_count + postamble_count;
439         for (; i < k; ++i, ++j) {
440                 if (postamble_data[j >> 3L] & (1L << (j & 7L)))
441                         buffer[i >> 3L] |= (1L << (i & 7L));
442                 else
443                         buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));
444
445         }
446 }
447
448 static int alt_jtag_drscan(struct altera_state *astate,
449                         int start_state,
450                         int count,
451                         u8 *tdi,
452                         u8 *tdo)
453 {
454         int i = 0;
455         int tdo_bit = 0;
456         int status = 1;
457
458         /* First go to DRSHIFT state */
459         switch (start_state) {
460         case 0:                                         /* IDLE */
461                 alt_jtag_io(1, 0, 0);   /* DRSELECT */
462                 alt_jtag_io(0, 0, 0);   /* DRCAPTURE */
463                 alt_jtag_io(0, 0, 0);   /* DRSHIFT */
464                 break;
465
466         case 1:                                         /* DRPAUSE */
467                 alt_jtag_io(1, 0, 0);   /* DREXIT2 */
468                 alt_jtag_io(1, 0, 0);   /* DRUPDATE */
469                 alt_jtag_io(1, 0, 0);   /* DRSELECT */
470                 alt_jtag_io(0, 0, 0);   /* DRCAPTURE */
471                 alt_jtag_io(0, 0, 0);   /* DRSHIFT */
472                 break;
473
474         case 2:                                         /* IRPAUSE */
475                 alt_jtag_io(1, 0, 0);   /* IREXIT2 */
476                 alt_jtag_io(1, 0, 0);   /* IRUPDATE */
477                 alt_jtag_io(1, 0, 0);   /* DRSELECT */
478                 alt_jtag_io(0, 0, 0);   /* DRCAPTURE */
479                 alt_jtag_io(0, 0, 0);   /* DRSHIFT */
480                 break;
481
482         default:
483                 status = 0;
484         }
485
486         if (status) {
487                 /* loop in the SHIFT-DR state */
488                 for (i = 0; i < count; i++) {
489                         tdo_bit = alt_jtag_io(
490                                         (i == count - 1),
491                                         tdi[i >> 3] & (1 << (i & 7)),
492                                         (tdo != NULL));
493
494                         if (tdo != NULL) {
495                                 if (tdo_bit)
496                                         tdo[i >> 3] |= (1 << (i & 7));
497                                 else
498                                         tdo[i >> 3] &= ~(u32)(1 << (i & 7));
499
500                         }
501                 }
502
503                 alt_jtag_io(0, 0, 0);   /* DRPAUSE */
504         }
505
506         return status;
507 }
508
509 static int alt_jtag_irscan(struct altera_state *astate,
510                     int start_state,
511                     int count,
512                     u8 *tdi,
513                     u8 *tdo)
514 {
515         int i = 0;
516         int tdo_bit = 0;
517         int status = 1;
518
519         /* First go to IRSHIFT state */
520         switch (start_state) {
521         case 0:                                         /* IDLE */
522                 alt_jtag_io(1, 0, 0);   /* DRSELECT */
523                 alt_jtag_io(1, 0, 0);   /* IRSELECT */
524                 alt_jtag_io(0, 0, 0);   /* IRCAPTURE */
525                 alt_jtag_io(0, 0, 0);   /* IRSHIFT */
526                 break;
527
528         case 1:                                         /* DRPAUSE */
529                 alt_jtag_io(1, 0, 0);   /* DREXIT2 */
530                 alt_jtag_io(1, 0, 0);   /* DRUPDATE */
531                 alt_jtag_io(1, 0, 0);   /* DRSELECT */
532                 alt_jtag_io(1, 0, 0);   /* IRSELECT */
533                 alt_jtag_io(0, 0, 0);   /* IRCAPTURE */
534                 alt_jtag_io(0, 0, 0);   /* IRSHIFT */
535                 break;
536
537         case 2:                                         /* IRPAUSE */
538                 alt_jtag_io(1, 0, 0);   /* IREXIT2 */
539                 alt_jtag_io(1, 0, 0);   /* IRUPDATE */
540                 alt_jtag_io(1, 0, 0);   /* DRSELECT */
541                 alt_jtag_io(1, 0, 0);   /* IRSELECT */
542                 alt_jtag_io(0, 0, 0);   /* IRCAPTURE */
543                 alt_jtag_io(0, 0, 0);   /* IRSHIFT */
544                 break;
545
546         default:
547                 status = 0;
548         }
549
550         if (status) {
551                 /* loop in the SHIFT-IR state */
552                 for (i = 0; i < count; i++) {
553                         tdo_bit = alt_jtag_io(
554                                       (i == count - 1),
555                                       tdi[i >> 3] & (1 << (i & 7)),
556                                       (tdo != NULL));
557                         if (tdo != NULL) {
558                                 if (tdo_bit)
559                                         tdo[i >> 3] |= (1 << (i & 7));
560                                 else
561                                         tdo[i >> 3] &= ~(u32)(1 << (i & 7));
562
563                         }
564                 }
565
566                 alt_jtag_io(0, 0, 0);   /* IRPAUSE */
567         }
568
569         return status;
570 }
571
572 static void altera_extract_target_data(u8 *buffer,
573                                 u8 *target_data,
574                                 u32 start_index,
575                                 u32 preamble_count,
576                                 u32 target_count)
577 /*
578  * Copies target data from scan buffer, filtering out
579  * preamble and postamble data.
580  */
581 {
582         u32 i;
583         u32 j;
584         u32 k;
585
586         j = preamble_count;
587         k = start_index + target_count;
588         for (i = start_index; i < k; ++i, ++j) {
589                 if (buffer[j >> 3] & (1 << (j & 7)))
590                         target_data[i >> 3] |= (1 << (i & 7));
591                 else
592                         target_data[i >> 3] &= ~(u32)(1 << (i & 7));
593
594         }
595 }
596
597 int altera_irscan(struct altera_state *astate,
598                                 u32 count,
599                                 u8 *tdi_data,
600                                 u32 start_index)
601 /* Shifts data into instruction register */
602 {
603         struct altera_jtag *js = &astate->js;
604         int start_code = 0;
605         u32 alloc_chars = 0;
606         u32 shift_count = js->ir_pre + count + js->ir_post;
607         int status = 0;
608         enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
609
610         switch (js->jtag_state) {
611         case ILLEGAL_JTAG_STATE:
612         case RESET:
613         case IDLE:
614                 start_code = 0;
615                 start_state = IDLE;
616                 break;
617
618         case DRSELECT:
619         case DRCAPTURE:
620         case DRSHIFT:
621         case DREXIT1:
622         case DRPAUSE:
623         case DREXIT2:
624         case DRUPDATE:
625                 start_code = 1;
626                 start_state = DRPAUSE;
627                 break;
628
629         case IRSELECT:
630         case IRCAPTURE:
631         case IRSHIFT:
632         case IREXIT1:
633         case IRPAUSE:
634         case IREXIT2:
635         case IRUPDATE:
636                 start_code = 2;
637                 start_state = IRPAUSE;
638                 break;
639
640         default:
641                 status = -EREMOTEIO;
642                 break;
643         }
644
645         if (status == 0)
646                 if (js->jtag_state != start_state)
647                         status = altera_goto_jstate(astate, start_state);
648
649         if (status == 0) {
650                 if (shift_count > js->ir_length) {
651                         alloc_chars = (shift_count + 7) >> 3;
652                         kfree(js->ir_buffer);
653                         js->ir_buffer = (u8 *)alt_malloc(alloc_chars);
654                         if (js->ir_buffer == NULL)
655                                 status = -ENOMEM;
656                         else
657                                 js->ir_length = alloc_chars * 8;
658
659                 }
660         }
661
662         if (status == 0) {
663                 /*
664                  * Copy preamble data, IR data,
665                  * and postamble data into a buffer
666                  */
667                 altera_concatenate_data(js->ir_buffer,
668                                         js->ir_pre_data,
669                                         js->ir_pre,
670                                         tdi_data,
671                                         start_index,
672                                         count,
673                                         js->ir_post_data,
674                                         js->ir_post);
675                 /* Do the IRSCAN */
676                 alt_jtag_irscan(astate,
677                                 start_code,
678                                 shift_count,
679                                 js->ir_buffer,
680                                 NULL);
681
682                 /* alt_jtag_irscan() always ends in IRPAUSE state */
683                 js->jtag_state = IRPAUSE;
684         }
685
686         if (status == 0)
687                 if (js->irstop_state != IRPAUSE)
688                         status = altera_goto_jstate(astate, js->irstop_state);
689
690
691         return status;
692 }
693
694 int altera_swap_ir(struct altera_state *astate,
695                             u32 count,
696                             u8 *in_data,
697                             u32 in_index,
698                             u8 *out_data,
699                             u32 out_index)
700 /* Shifts data into instruction register, capturing output data */
701 {
702         struct altera_jtag *js = &astate->js;
703         int start_code = 0;
704         u32 alloc_chars = 0;
705         u32 shift_count = js->ir_pre + count + js->ir_post;
706         int status = 0;
707         enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
708
709         switch (js->jtag_state) {
710         case ILLEGAL_JTAG_STATE:
711         case RESET:
712         case IDLE:
713                 start_code = 0;
714                 start_state = IDLE;
715                 break;
716
717         case DRSELECT:
718         case DRCAPTURE:
719         case DRSHIFT:
720         case DREXIT1:
721         case DRPAUSE:
722         case DREXIT2:
723         case DRUPDATE:
724                 start_code = 1;
725                 start_state = DRPAUSE;
726                 break;
727
728         case IRSELECT:
729         case IRCAPTURE:
730         case IRSHIFT:
731         case IREXIT1:
732         case IRPAUSE:
733         case IREXIT2:
734         case IRUPDATE:
735                 start_code = 2;
736                 start_state = IRPAUSE;
737                 break;
738
739         default:
740                 status = -EREMOTEIO;
741                 break;
742         }
743
744         if (status == 0)
745                 if (js->jtag_state != start_state)
746                         status = altera_goto_jstate(astate, start_state);
747
748         if (status == 0) {
749                 if (shift_count > js->ir_length) {
750                         alloc_chars = (shift_count + 7) >> 3;
751                         kfree(js->ir_buffer);
752                         js->ir_buffer = (u8 *)alt_malloc(alloc_chars);
753                         if (js->ir_buffer == NULL)
754                                 status = -ENOMEM;
755                         else
756                                 js->ir_length = alloc_chars * 8;
757
758                 }
759         }
760
761         if (status == 0) {
762                 /*
763                  * Copy preamble data, IR data,
764                  * and postamble data into a buffer
765                  */
766                 altera_concatenate_data(js->ir_buffer,
767                                         js->ir_pre_data,
768                                         js->ir_pre,
769                                         in_data,
770                                         in_index,
771                                         count,
772                                         js->ir_post_data,
773                                         js->ir_post);
774
775                 /* Do the IRSCAN */
776                 alt_jtag_irscan(astate,
777                                 start_code,
778                                 shift_count,
779                                 js->ir_buffer,
780                                 js->ir_buffer);
781
782                 /* alt_jtag_irscan() always ends in IRPAUSE state */
783                 js->jtag_state = IRPAUSE;
784         }
785
786         if (status == 0)
787                 if (js->irstop_state != IRPAUSE)
788                         status = altera_goto_jstate(astate, js->irstop_state);
789
790
791         if (status == 0)
792                 /* Now extract the returned data from the buffer */
793                 altera_extract_target_data(js->ir_buffer,
794                                         out_data, out_index,
795                                         js->ir_pre, count);
796
797         return status;
798 }
799
800 int altera_drscan(struct altera_state *astate,
801                                 u32 count,
802                                 u8 *tdi_data,
803                                 u32 start_index)
804 /* Shifts data into data register (ignoring output data) */
805 {
806         struct altera_jtag *js = &astate->js;
807         int start_code = 0;
808         u32 alloc_chars = 0;
809         u32 shift_count = js->dr_pre + count + js->dr_post;
810         int status = 0;
811         enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
812
813         switch (js->jtag_state) {
814         case ILLEGAL_JTAG_STATE:
815         case RESET:
816         case IDLE:
817                 start_code = 0;
818                 start_state = IDLE;
819                 break;
820
821         case DRSELECT:
822         case DRCAPTURE:
823         case DRSHIFT:
824         case DREXIT1:
825         case DRPAUSE:
826         case DREXIT2:
827         case DRUPDATE:
828                 start_code = 1;
829                 start_state = DRPAUSE;
830                 break;
831
832         case IRSELECT:
833         case IRCAPTURE:
834         case IRSHIFT:
835         case IREXIT1:
836         case IRPAUSE:
837         case IREXIT2:
838         case IRUPDATE:
839                 start_code = 2;
840                 start_state = IRPAUSE;
841                 break;
842
843         default:
844                 status = -EREMOTEIO;
845                 break;
846         }
847
848         if (status == 0)
849                 if (js->jtag_state != start_state)
850                         status = altera_goto_jstate(astate, start_state);
851
852         if (status == 0) {
853                 if (shift_count > js->dr_length) {
854                         alloc_chars = (shift_count + 7) >> 3;
855                         kfree(js->dr_buffer);
856                         js->dr_buffer = (u8 *)alt_malloc(alloc_chars);
857                         if (js->dr_buffer == NULL)
858                                 status = -ENOMEM;
859                         else
860                                 js->dr_length = alloc_chars * 8;
861
862                 }
863         }
864
865         if (status == 0) {
866                 /*
867                  * Copy preamble data, DR data,
868                  * and postamble data into a buffer
869                  */
870                 altera_concatenate_data(js->dr_buffer,
871                                         js->dr_pre_data,
872                                         js->dr_pre,
873                                         tdi_data,
874                                         start_index,
875                                         count,
876                                         js->dr_post_data,
877                                         js->dr_post);
878                 /* Do the DRSCAN */
879                 alt_jtag_drscan(astate, start_code, shift_count,
880                                 js->dr_buffer, NULL);
881                 /* alt_jtag_drscan() always ends in DRPAUSE state */
882                 js->jtag_state = DRPAUSE;
883         }
884
885         if (status == 0)
886                 if (js->drstop_state != DRPAUSE)
887                         status = altera_goto_jstate(astate, js->drstop_state);
888
889         return status;
890 }
891
892 int altera_swap_dr(struct altera_state *astate, u32 count,
893                                 u8 *in_data, u32 in_index,
894                                 u8 *out_data, u32 out_index)
895 /* Shifts data into data register, capturing output data */
896 {
897         struct altera_jtag *js = &astate->js;
898         int start_code = 0;
899         u32 alloc_chars = 0;
900         u32 shift_count = js->dr_pre + count + js->dr_post;
901         int status = 0;
902         enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
903
904         switch (js->jtag_state) {
905         case ILLEGAL_JTAG_STATE:
906         case RESET:
907         case IDLE:
908                 start_code = 0;
909                 start_state = IDLE;
910                 break;
911
912         case DRSELECT:
913         case DRCAPTURE:
914         case DRSHIFT:
915         case DREXIT1:
916         case DRPAUSE:
917         case DREXIT2:
918         case DRUPDATE:
919                 start_code = 1;
920                 start_state = DRPAUSE;
921                 break;
922
923         case IRSELECT:
924         case IRCAPTURE:
925         case IRSHIFT:
926         case IREXIT1:
927         case IRPAUSE:
928         case IREXIT2:
929         case IRUPDATE:
930                 start_code = 2;
931                 start_state = IRPAUSE;
932                 break;
933
934         default:
935                 status = -EREMOTEIO;
936                 break;
937         }
938
939         if (status == 0)
940                 if (js->jtag_state != start_state)
941                         status = altera_goto_jstate(astate, start_state);
942
943         if (status == 0) {
944                 if (shift_count > js->dr_length) {
945                         alloc_chars = (shift_count + 7) >> 3;
946                         kfree(js->dr_buffer);
947                         js->dr_buffer = (u8 *)alt_malloc(alloc_chars);
948
949                         if (js->dr_buffer == NULL)
950                                 status = -ENOMEM;
951                         else
952                                 js->dr_length = alloc_chars * 8;
953
954                 }
955         }
956
957         if (status == 0) {
958                 /*
959                  * Copy preamble data, DR data,
960                  * and postamble data into a buffer
961                  */
962                 altera_concatenate_data(js->dr_buffer,
963                                 js->dr_pre_data,
964                                 js->dr_pre,
965                                 in_data,
966                                 in_index,
967                                 count,
968                                 js->dr_post_data,
969                                 js->dr_post);
970
971                 /* Do the DRSCAN */
972                 alt_jtag_drscan(astate,
973                                 start_code,
974                                 shift_count,
975                                 js->dr_buffer,
976                                 js->dr_buffer);
977
978                 /* alt_jtag_drscan() always ends in DRPAUSE state */
979                 js->jtag_state = DRPAUSE;
980         }
981
982         if (status == 0)
983                 if (js->drstop_state != DRPAUSE)
984                         status = altera_goto_jstate(astate, js->drstop_state);
985
986         if (status == 0)
987                 /* Now extract the returned data from the buffer */
988                 altera_extract_target_data(js->dr_buffer,
989                                         out_data,
990                                         out_index,
991                                         js->dr_pre,
992                                         count);
993
994         return status;
995 }
996
997 void altera_free_buffers(struct altera_state *astate)
998 {
999         struct altera_jtag *js = &astate->js;
1000         /* If the JTAG interface was used, reset it to TLR */
1001         if (js->jtag_state != ILLEGAL_JTAG_STATE)
1002                 altera_jreset_idle(astate);
1003
1004         kfree(js->dr_pre_data);
1005         js->dr_pre_data = NULL;
1006
1007         kfree(js->dr_post_data);
1008         js->dr_post_data = NULL;
1009
1010         kfree(js->dr_buffer);
1011         js->dr_buffer = NULL;
1012
1013         kfree(js->ir_pre_data);
1014         js->ir_pre_data = NULL;
1015
1016         kfree(js->ir_post_data);
1017         js->ir_post_data = NULL;
1018
1019         kfree(js->ir_buffer);
1020         js->ir_buffer = NULL;
1021 }