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/firmware.h>
27 #include <linux/slab.h>
28 #include <staging/altera.h>
29 #include "altera-exprt.h"
30 #include "altera-jtag.h"
32 #define alt_jtag_io(a, b, c)\
33 astate->config->jtag_io(astate->config->dev, a, b, c);
35 #define alt_malloc(a) kzalloc(a, GFP_KERNEL);
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.
42 struct altera_jtag_machine {
43 enum altera_jtag_state tms_high;
44 enum altera_jtag_state tms_low;
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 }
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.
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
80 /* Flag bits for alt_jtag_io() function */
88 int altera_jinit(struct altera_state *astate)
90 struct altera_jtag *js = &astate->js;
92 /* initial JTAG state is unknown */
93 js->jtag_state = ILLEGAL_JTAG_STATE;
95 /* initialize to default state */
96 js->drstop_state = IDLE;
97 js->irstop_state = IDLE;
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;
115 int altera_set_drstop(struct altera_jtag *js, enum altera_jtag_state state)
117 js->drstop_state = state;
122 int altera_set_irstop(struct altera_jtag *js, enum altera_jtag_state state)
124 js->irstop_state = state;
129 int altera_set_dr_pre(struct altera_jtag *js,
130 u32 count, u32 start_index,
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)
148 for (i = 0; i < count; ++i) {
151 if (preamble_data == NULL)
152 js->dr_pre_data[i >> 3] |= (1 << (i & 7));
154 if (preamble_data[j >> 3] & (1 << (j & 7)))
155 js->dr_pre_data[i >> 3] |=
158 js->dr_pre_data[i >> 3] &=
159 ~(u32)(1 << (i & 7));
168 int altera_set_ir_pre(struct altera_jtag *js, u32 count, u32 start_index,
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)
187 for (i = 0; i < count; ++i) {
189 if (preamble_data == NULL)
190 js->ir_pre_data[i >> 3] |= (1 << (i & 7));
192 if (preamble_data[j >> 3] & (1 << (j & 7)))
193 js->ir_pre_data[i >> 3] |=
196 js->ir_pre_data[i >> 3] &=
197 ~(u32)(1 << (i & 7));
206 int altera_set_dr_post(struct altera_jtag *js, u32 count, u32 start_index,
213 if (count > js->dr_post) {
214 kfree(js->dr_post_data);
215 js->dr_post_data = (u8 *)alt_malloc((count + 7) >> 3);
217 if (js->dr_post_data == NULL)
226 for (i = 0; i < count; ++i) {
229 if (postamble_data == NULL)
230 js->dr_post_data[i >> 3] |= (1 << (i & 7));
232 if (postamble_data[j >> 3] & (1 << (j & 7)))
233 js->dr_post_data[i >> 3] |=
236 js->dr_post_data[i >> 3] &=
237 ~(u32)(1 << (i & 7));
246 int altera_set_ir_post(struct altera_jtag *js, u32 count, u32 start_index,
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)
267 for (i = 0; i < count; ++i) {
270 if (postamble_data == NULL)
271 js->ir_post_data[i >> 3] |= (1 << (i & 7));
273 if (postamble_data[j >> 3] & (1 << (j & 7)))
274 js->ir_post_data[i >> 3] |= (1 << (i & 7));
276 js->ir_post_data[i >> 3] &=
277 ~(u32)(1 << (i & 7));
285 static void altera_jreset_idle(struct altera_state *astate)
287 struct altera_jtag *js = &astate->js;
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);
293 /* Now step to Run Test / Idle */
294 alt_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
295 js->jtag_state = IDLE;
298 int altera_goto_jstate(struct altera_state *astate,
299 enum altera_jtag_state state)
301 struct altera_jtag *js = &astate->js;
306 if (js->jtag_state == ILLEGAL_JTAG_STATE)
307 /* initialize JTAG chain to known state */
308 altera_jreset_idle(astate);
310 if (js->jtag_state == state) {
312 * We are already in the desired state.
313 * If it is a stable state, loop here.
314 * Otherwise do nothing (no clock cycles).
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);
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] &
328 ? TMS_HIGH : TMS_LOW;
331 alt_jtag_io(tms, TDI_LOW, IGNORE_TDO);
335 altera_transitions[js->jtag_state].tms_high;
338 altera_transitions[js->jtag_state].tms_low;
344 if (js->jtag_state != state)
350 int altera_wait_cycles(struct altera_state *astate,
352 enum altera_jtag_state wait_state)
354 struct altera_jtag *js = &astate->js;
359 if (js->jtag_state != wait_state)
360 status = altera_goto_jstate(astate, wait_state);
364 * Set TMS high to loop in RESET state
365 * Set TMS low to loop in any other stable state
367 tms = (wait_state == RESET) ? TMS_HIGH : TMS_LOW;
369 for (count = 0L; count < cycles; count++)
370 alt_jtag_io(tms, TDI_LOW, IGNORE_TDO);
377 int altera_wait_msecs(struct altera_state *astate,
378 s32 microseconds, enum altera_jtag_state wait_state)
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.
389 struct altera_jtag *js = &astate->js;
392 if ((js->jtag_state != ILLEGAL_JTAG_STATE) &&
393 (js->jtag_state != wait_state))
394 status = altera_goto_jstate(astate, wait_state);
397 /* Wait for specified time interval */
398 udelay(microseconds);
403 static void altera_concatenate_data(u8 *buffer,
412 * Copies preamble data, target data, and postamble data
413 * into one buffer for IR or DR scans.
418 for (i = 0L; i < preamble_count; ++i) {
419 if (preamble_data[i >> 3L] & (1L << (i & 7L)))
420 buffer[i >> 3L] |= (1L << (i & 7L));
422 buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));
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));
432 buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));
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));
442 buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));
447 static int alt_jtag_drscan(struct altera_state *astate,
457 /* First go to DRSHIFT state */
458 switch (start_state) {
460 alt_jtag_io(1, 0, 0); /* DRSELECT */
461 alt_jtag_io(0, 0, 0); /* DRCAPTURE */
462 alt_jtag_io(0, 0, 0); /* DRSHIFT */
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 */
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 */
486 /* loop in the SHIFT-DR state */
487 for (i = 0; i < count; i++) {
488 tdo_bit = alt_jtag_io(
490 tdi[i >> 3] & (1 << (i & 7)),
495 tdo[i >> 3] |= (1 << (i & 7));
497 tdo[i >> 3] &= ~(u32)(1 << (i & 7));
502 alt_jtag_io(0, 0, 0); /* DRPAUSE */
508 static int alt_jtag_irscan(struct altera_state *astate,
518 /* First go to IRSHIFT state */
519 switch (start_state) {
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 */
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 */
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 */
550 /* loop in the SHIFT-IR state */
551 for (i = 0; i < count; i++) {
552 tdo_bit = alt_jtag_io(
554 tdi[i >> 3] & (1 << (i & 7)),
558 tdo[i >> 3] |= (1 << (i & 7));
560 tdo[i >> 3] &= ~(u32)(1 << (i & 7));
565 alt_jtag_io(0, 0, 0); /* IRPAUSE */
571 static void altera_extract_target_data(u8 *buffer,
577 * Copies target data from scan buffer, filtering out
578 * preamble and postamble data.
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));
591 target_data[i >> 3] &= ~(u32)(1 << (i & 7));
596 int altera_irscan(struct altera_state *astate,
600 /* Shifts data into instruction register */
602 struct altera_jtag *js = &astate->js;
605 u32 shift_count = js->ir_pre + count + js->ir_post;
607 enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
609 switch (js->jtag_state) {
610 case ILLEGAL_JTAG_STATE:
625 start_state = DRPAUSE;
636 start_state = IRPAUSE;
645 if (js->jtag_state != start_state)
646 status = altera_goto_jstate(astate, start_state);
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)
656 js->ir_length = alloc_chars * 8;
663 * Copy preamble data, IR data,
664 * and postamble data into a buffer
666 altera_concatenate_data(js->ir_buffer,
675 alt_jtag_irscan(astate,
681 /* alt_jtag_irscan() always ends in IRPAUSE state */
682 js->jtag_state = IRPAUSE;
686 if (js->irstop_state != IRPAUSE)
687 status = altera_goto_jstate(astate, js->irstop_state);
693 int altera_swap_ir(struct altera_state *astate,
699 /* Shifts data into instruction register, capturing output data */
701 struct altera_jtag *js = &astate->js;
704 u32 shift_count = js->ir_pre + count + js->ir_post;
706 enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
708 switch (js->jtag_state) {
709 case ILLEGAL_JTAG_STATE:
724 start_state = DRPAUSE;
735 start_state = IRPAUSE;
744 if (js->jtag_state != start_state)
745 status = altera_goto_jstate(astate, start_state);
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)
755 js->ir_length = alloc_chars * 8;
762 * Copy preamble data, IR data,
763 * and postamble data into a buffer
765 altera_concatenate_data(js->ir_buffer,
775 alt_jtag_irscan(astate,
781 /* alt_jtag_irscan() always ends in IRPAUSE state */
782 js->jtag_state = IRPAUSE;
786 if (js->irstop_state != IRPAUSE)
787 status = altera_goto_jstate(astate, js->irstop_state);
791 /* Now extract the returned data from the buffer */
792 altera_extract_target_data(js->ir_buffer,
799 int altera_drscan(struct altera_state *astate,
803 /* Shifts data into data register (ignoring output data) */
805 struct altera_jtag *js = &astate->js;
808 u32 shift_count = js->dr_pre + count + js->dr_post;
810 enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
812 switch (js->jtag_state) {
813 case ILLEGAL_JTAG_STATE:
828 start_state = DRPAUSE;
839 start_state = IRPAUSE;
848 if (js->jtag_state != start_state)
849 status = altera_goto_jstate(astate, start_state);
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)
859 js->dr_length = alloc_chars * 8;
866 * Copy preamble data, DR data,
867 * and postamble data into a buffer
869 altera_concatenate_data(js->dr_buffer,
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;
885 if (js->drstop_state != DRPAUSE)
886 status = altera_goto_jstate(astate, js->drstop_state);
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 */
896 struct altera_jtag *js = &astate->js;
899 u32 shift_count = js->dr_pre + count + js->dr_post;
901 enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
903 switch (js->jtag_state) {
904 case ILLEGAL_JTAG_STATE:
919 start_state = DRPAUSE;
930 start_state = IRPAUSE;
939 if (js->jtag_state != start_state)
940 status = altera_goto_jstate(astate, start_state);
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);
948 if (js->dr_buffer == NULL)
951 js->dr_length = alloc_chars * 8;
958 * Copy preamble data, DR data,
959 * and postamble data into a buffer
961 altera_concatenate_data(js->dr_buffer,
971 alt_jtag_drscan(astate,
977 /* alt_jtag_drscan() always ends in DRPAUSE state */
978 js->jtag_state = DRPAUSE;
982 if (js->drstop_state != DRPAUSE)
983 status = altera_goto_jstate(astate, js->drstop_state);
986 /* Now extract the returned data from the buffer */
987 altera_extract_target_data(js->dr_buffer,
996 void altera_free_buffers(struct altera_state *astate)
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);
1003 kfree(js->dr_pre_data);
1004 js->dr_pre_data = NULL;
1006 kfree(js->dr_post_data);
1007 js->dr_post_data = NULL;
1009 kfree(js->dr_buffer);
1010 js->dr_buffer = NULL;
1012 kfree(js->ir_pre_data);
1013 js->ir_pre_data = NULL;
1015 kfree(js->ir_post_data);
1016 js->ir_post_data = NULL;
1018 kfree(js->ir_buffer);
1019 js->ir_buffer = NULL;