6 * Copyright (C) Altera Corporation 1998-2001
7 * Copyright (C) 2010 NetUP Inc.
8 * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
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.
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
19 * GNU General Public License for more details.
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.
26 #include <linux/delay.h>
27 #include <linux/firmware.h>
28 #include <linux/slab.h>
30 #include "altera-exprt.h"
31 #include "altera-jtag.h"
33 #define alt_jtag_io(a, b, c)\
34 astate->config->jtag_io(astate->config->dev, a, b, c);
36 #define alt_malloc(a) kzalloc(a, GFP_KERNEL);
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.
43 struct altera_jtag_machine
{
44 enum altera_jtag_state tms_high
;
45 enum altera_jtag_state tms_low
;
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
}
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.
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
81 /* Flag bits for alt_jtag_io() function */
89 int altera_jinit(struct altera_state
*astate
)
91 struct altera_jtag
*js
= &astate
->js
;
93 /* initial JTAG state is unknown */
94 js
->jtag_state
= ILLEGAL_JTAG_STATE
;
96 /* initialize to default state */
97 js
->drstop_state
= IDLE
;
98 js
->irstop_state
= IDLE
;
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
;
116 int altera_set_drstop(struct altera_jtag
*js
, enum altera_jtag_state state
)
118 js
->drstop_state
= state
;
123 int altera_set_irstop(struct altera_jtag
*js
, enum altera_jtag_state state
)
125 js
->irstop_state
= state
;
130 int altera_set_dr_pre(struct altera_jtag
*js
,
131 u32 count
, u32 start_index
,
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
)
149 for (i
= 0; i
< count
; ++i
) {
152 if (preamble_data
== NULL
)
153 js
->dr_pre_data
[i
>> 3] |= (1 << (i
& 7));
155 if (preamble_data
[j
>> 3] & (1 << (j
& 7)))
156 js
->dr_pre_data
[i
>> 3] |=
159 js
->dr_pre_data
[i
>> 3] &=
160 ~(u32
)(1 << (i
& 7));
169 int altera_set_ir_pre(struct altera_jtag
*js
, u32 count
, u32 start_index
,
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
)
188 for (i
= 0; i
< count
; ++i
) {
190 if (preamble_data
== NULL
)
191 js
->ir_pre_data
[i
>> 3] |= (1 << (i
& 7));
193 if (preamble_data
[j
>> 3] & (1 << (j
& 7)))
194 js
->ir_pre_data
[i
>> 3] |=
197 js
->ir_pre_data
[i
>> 3] &=
198 ~(u32
)(1 << (i
& 7));
207 int altera_set_dr_post(struct altera_jtag
*js
, u32 count
, u32 start_index
,
214 if (count
> js
->dr_post
) {
215 kfree(js
->dr_post_data
);
216 js
->dr_post_data
= (u8
*)alt_malloc((count
+ 7) >> 3);
218 if (js
->dr_post_data
== NULL
)
227 for (i
= 0; i
< count
; ++i
) {
230 if (postamble_data
== NULL
)
231 js
->dr_post_data
[i
>> 3] |= (1 << (i
& 7));
233 if (postamble_data
[j
>> 3] & (1 << (j
& 7)))
234 js
->dr_post_data
[i
>> 3] |=
237 js
->dr_post_data
[i
>> 3] &=
238 ~(u32
)(1 << (i
& 7));
247 int altera_set_ir_post(struct altera_jtag
*js
, u32 count
, u32 start_index
,
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
)
268 for (i
= 0; i
< count
; ++i
) {
271 if (postamble_data
== NULL
)
272 js
->ir_post_data
[i
>> 3] |= (1 << (i
& 7));
274 if (postamble_data
[j
>> 3] & (1 << (j
& 7)))
275 js
->ir_post_data
[i
>> 3] |= (1 << (i
& 7));
277 js
->ir_post_data
[i
>> 3] &=
278 ~(u32
)(1 << (i
& 7));
286 static void altera_jreset_idle(struct altera_state
*astate
)
288 struct altera_jtag
*js
= &astate
->js
;
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
);
294 /* Now step to Run Test / Idle */
295 alt_jtag_io(TMS_LOW
, TDI_LOW
, IGNORE_TDO
);
296 js
->jtag_state
= IDLE
;
299 int altera_goto_jstate(struct altera_state
*astate
,
300 enum altera_jtag_state state
)
302 struct altera_jtag
*js
= &astate
->js
;
307 if (js
->jtag_state
== ILLEGAL_JTAG_STATE
)
308 /* initialize JTAG chain to known state */
309 altera_jreset_idle(astate
);
311 if (js
->jtag_state
== state
) {
313 * We are already in the desired state.
314 * If it is a stable state, loop here.
315 * Otherwise do nothing (no clock cycles).
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
);
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
] &
329 ? TMS_HIGH
: TMS_LOW
;
332 alt_jtag_io(tms
, TDI_LOW
, IGNORE_TDO
);
336 altera_transitions
[js
->jtag_state
].tms_high
;
339 altera_transitions
[js
->jtag_state
].tms_low
;
345 if (js
->jtag_state
!= state
)
351 int altera_wait_cycles(struct altera_state
*astate
,
353 enum altera_jtag_state wait_state
)
355 struct altera_jtag
*js
= &astate
->js
;
360 if (js
->jtag_state
!= wait_state
)
361 status
= altera_goto_jstate(astate
, wait_state
);
365 * Set TMS high to loop in RESET state
366 * Set TMS low to loop in any other stable state
368 tms
= (wait_state
== RESET
) ? TMS_HIGH
: TMS_LOW
;
370 for (count
= 0L; count
< cycles
; count
++)
371 alt_jtag_io(tms
, TDI_LOW
, IGNORE_TDO
);
378 int altera_wait_msecs(struct altera_state
*astate
,
379 s32 microseconds
, enum altera_jtag_state wait_state
)
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.
390 struct altera_jtag
*js
= &astate
->js
;
393 if ((js
->jtag_state
!= ILLEGAL_JTAG_STATE
) &&
394 (js
->jtag_state
!= wait_state
))
395 status
= altera_goto_jstate(astate
, wait_state
);
398 /* Wait for specified time interval */
399 udelay(microseconds
);
404 static void altera_concatenate_data(u8
*buffer
,
413 * Copies preamble data, target data, and postamble data
414 * into one buffer for IR or DR scans.
419 for (i
= 0L; i
< preamble_count
; ++i
) {
420 if (preamble_data
[i
>> 3L] & (1L << (i
& 7L)))
421 buffer
[i
>> 3L] |= (1L << (i
& 7L));
423 buffer
[i
>> 3L] &= ~(u32
)(1L << (i
& 7L));
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));
433 buffer
[i
>> 3L] &= ~(u32
)(1L << (i
& 7L));
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));
443 buffer
[i
>> 3L] &= ~(u32
)(1L << (i
& 7L));
448 static int alt_jtag_drscan(struct altera_state
*astate
,
458 /* First go to DRSHIFT state */
459 switch (start_state
) {
461 alt_jtag_io(1, 0, 0); /* DRSELECT */
462 alt_jtag_io(0, 0, 0); /* DRCAPTURE */
463 alt_jtag_io(0, 0, 0); /* DRSHIFT */
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 */
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 */
487 /* loop in the SHIFT-DR state */
488 for (i
= 0; i
< count
; i
++) {
489 tdo_bit
= alt_jtag_io(
491 tdi
[i
>> 3] & (1 << (i
& 7)),
496 tdo
[i
>> 3] |= (1 << (i
& 7));
498 tdo
[i
>> 3] &= ~(u32
)(1 << (i
& 7));
503 alt_jtag_io(0, 0, 0); /* DRPAUSE */
509 static int alt_jtag_irscan(struct altera_state
*astate
,
519 /* First go to IRSHIFT state */
520 switch (start_state
) {
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 */
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 */
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 */
551 /* loop in the SHIFT-IR state */
552 for (i
= 0; i
< count
; i
++) {
553 tdo_bit
= alt_jtag_io(
555 tdi
[i
>> 3] & (1 << (i
& 7)),
559 tdo
[i
>> 3] |= (1 << (i
& 7));
561 tdo
[i
>> 3] &= ~(u32
)(1 << (i
& 7));
566 alt_jtag_io(0, 0, 0); /* IRPAUSE */
572 static void altera_extract_target_data(u8
*buffer
,
578 * Copies target data from scan buffer, filtering out
579 * preamble and postamble data.
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));
592 target_data
[i
>> 3] &= ~(u32
)(1 << (i
& 7));
597 int altera_irscan(struct altera_state
*astate
,
601 /* Shifts data into instruction register */
603 struct altera_jtag
*js
= &astate
->js
;
606 u32 shift_count
= js
->ir_pre
+ count
+ js
->ir_post
;
608 enum altera_jtag_state start_state
= ILLEGAL_JTAG_STATE
;
610 switch (js
->jtag_state
) {
611 case ILLEGAL_JTAG_STATE
:
626 start_state
= DRPAUSE
;
637 start_state
= IRPAUSE
;
646 if (js
->jtag_state
!= start_state
)
647 status
= altera_goto_jstate(astate
, start_state
);
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
)
657 js
->ir_length
= alloc_chars
* 8;
664 * Copy preamble data, IR data,
665 * and postamble data into a buffer
667 altera_concatenate_data(js
->ir_buffer
,
676 alt_jtag_irscan(astate
,
682 /* alt_jtag_irscan() always ends in IRPAUSE state */
683 js
->jtag_state
= IRPAUSE
;
687 if (js
->irstop_state
!= IRPAUSE
)
688 status
= altera_goto_jstate(astate
, js
->irstop_state
);
694 int altera_swap_ir(struct altera_state
*astate
,
700 /* Shifts data into instruction register, capturing output data */
702 struct altera_jtag
*js
= &astate
->js
;
705 u32 shift_count
= js
->ir_pre
+ count
+ js
->ir_post
;
707 enum altera_jtag_state start_state
= ILLEGAL_JTAG_STATE
;
709 switch (js
->jtag_state
) {
710 case ILLEGAL_JTAG_STATE
:
725 start_state
= DRPAUSE
;
736 start_state
= IRPAUSE
;
745 if (js
->jtag_state
!= start_state
)
746 status
= altera_goto_jstate(astate
, start_state
);
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
)
756 js
->ir_length
= alloc_chars
* 8;
763 * Copy preamble data, IR data,
764 * and postamble data into a buffer
766 altera_concatenate_data(js
->ir_buffer
,
776 alt_jtag_irscan(astate
,
782 /* alt_jtag_irscan() always ends in IRPAUSE state */
783 js
->jtag_state
= IRPAUSE
;
787 if (js
->irstop_state
!= IRPAUSE
)
788 status
= altera_goto_jstate(astate
, js
->irstop_state
);
792 /* Now extract the returned data from the buffer */
793 altera_extract_target_data(js
->ir_buffer
,
800 int altera_drscan(struct altera_state
*astate
,
804 /* Shifts data into data register (ignoring output data) */
806 struct altera_jtag
*js
= &astate
->js
;
809 u32 shift_count
= js
->dr_pre
+ count
+ js
->dr_post
;
811 enum altera_jtag_state start_state
= ILLEGAL_JTAG_STATE
;
813 switch (js
->jtag_state
) {
814 case ILLEGAL_JTAG_STATE
:
829 start_state
= DRPAUSE
;
840 start_state
= IRPAUSE
;
849 if (js
->jtag_state
!= start_state
)
850 status
= altera_goto_jstate(astate
, start_state
);
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
)
860 js
->dr_length
= alloc_chars
* 8;
867 * Copy preamble data, DR data,
868 * and postamble data into a buffer
870 altera_concatenate_data(js
->dr_buffer
,
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
;
886 if (js
->drstop_state
!= DRPAUSE
)
887 status
= altera_goto_jstate(astate
, js
->drstop_state
);
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 */
897 struct altera_jtag
*js
= &astate
->js
;
900 u32 shift_count
= js
->dr_pre
+ count
+ js
->dr_post
;
902 enum altera_jtag_state start_state
= ILLEGAL_JTAG_STATE
;
904 switch (js
->jtag_state
) {
905 case ILLEGAL_JTAG_STATE
:
920 start_state
= DRPAUSE
;
931 start_state
= IRPAUSE
;
940 if (js
->jtag_state
!= start_state
)
941 status
= altera_goto_jstate(astate
, start_state
);
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
);
949 if (js
->dr_buffer
== NULL
)
952 js
->dr_length
= alloc_chars
* 8;
959 * Copy preamble data, DR data,
960 * and postamble data into a buffer
962 altera_concatenate_data(js
->dr_buffer
,
972 alt_jtag_drscan(astate
,
978 /* alt_jtag_drscan() always ends in DRPAUSE state */
979 js
->jtag_state
= DRPAUSE
;
983 if (js
->drstop_state
!= DRPAUSE
)
984 status
= altera_goto_jstate(astate
, js
->drstop_state
);
987 /* Now extract the returned data from the buffer */
988 altera_extract_target_data(js
->dr_buffer
,
997 void altera_free_buffers(struct altera_state
*astate
)
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
);
1004 kfree(js
->dr_pre_data
);
1005 js
->dr_pre_data
= NULL
;
1007 kfree(js
->dr_post_data
);
1008 js
->dr_post_data
= NULL
;
1010 kfree(js
->dr_buffer
);
1011 js
->dr_buffer
= NULL
;
1013 kfree(js
->ir_pre_data
);
1014 js
->ir_pre_data
= NULL
;
1016 kfree(js
->ir_post_data
);
1017 js
->ir_post_data
= NULL
;
1019 kfree(js
->ir_buffer
);
1020 js
->ir_buffer
= NULL
;