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