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 <misc/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 */
43struct altera_jtag_machine {
44	enum altera_jtag_state tms_high;
45	enum altera_jtag_state tms_low;
46};
47
48static 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 */
74static 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
89int 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
116int altera_set_drstop(struct altera_jtag *js, enum altera_jtag_state state)
117{
118	js->drstop_state = state;
119
120	return 0;
121}
122
123int altera_set_irstop(struct altera_jtag *js, enum altera_jtag_state state)
124{
125	js->irstop_state = state;
126
127	return 0;
128}
129
130int 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
169int 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
207int 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
247int 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
286static 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
299int 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
351int 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
378int 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
404static 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
448static 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
509static 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
572static 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
597int 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
694int 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
800int 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
892int 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
997void 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}
1022