6 * Copyright (C) Altera Corporation 1998-2001
7 * Copyright (C) 2010 NetUP Inc.
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>
29 #include <misc/altera.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;