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