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  */
29 struct altera_jtag_machine {
30 	enum altera_jtag_state tms_high;
31 	enum altera_jtag_state tms_low;
32 };
33 
34 static 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  */
60 static 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 
altera_jinit(struct altera_state * astate)75 int 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 
altera_set_drstop(struct altera_jtag * js,enum altera_jtag_state state)102 int altera_set_drstop(struct altera_jtag *js, enum altera_jtag_state state)
103 {
104 	js->drstop_state = state;
105 
106 	return 0;
107 }
108 
altera_set_irstop(struct altera_jtag * js,enum altera_jtag_state state)109 int altera_set_irstop(struct altera_jtag *js, enum altera_jtag_state state)
110 {
111 	js->irstop_state = state;
112 
113 	return 0;
114 }
115 
altera_set_dr_pre(struct altera_jtag * js,u32 count,u32 start_index,u8 * preamble_data)116 int 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 
altera_set_ir_pre(struct altera_jtag * js,u32 count,u32 start_index,u8 * preamble_data)155 int 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 
altera_set_dr_post(struct altera_jtag * js,u32 count,u32 start_index,u8 * postamble_data)193 int 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 
altera_set_ir_post(struct altera_jtag * js,u32 count,u32 start_index,u8 * postamble_data)233 int 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 
altera_jreset_idle(struct altera_state * astate)272 static 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 
altera_goto_jstate(struct altera_state * astate,enum altera_jtag_state state)285 int 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 
altera_wait_cycles(struct altera_state * astate,s32 cycles,enum altera_jtag_state wait_state)337 int 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 
altera_wait_msecs(struct altera_state * astate,s32 microseconds,enum altera_jtag_state wait_state)364 int 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 
altera_concatenate_data(u8 * buffer,u8 * preamble_data,u32 preamble_count,u8 * target_data,u32 start_index,u32 target_count,u8 * postamble_data,u32 postamble_count)390 static 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 
alt_jtag_drscan(struct altera_state * astate,int start_state,int count,u8 * tdi,u8 * tdo)434 static 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 
alt_jtag_irscan(struct altera_state * astate,int start_state,int count,u8 * tdi,u8 * tdo)495 static 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 
altera_extract_target_data(u8 * buffer,u8 * target_data,u32 start_index,u32 preamble_count,u32 target_count)558 static 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 
altera_irscan(struct altera_state * astate,u32 count,u8 * tdi_data,u32 start_index)583 int 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 
altera_swap_ir(struct altera_state * astate,u32 count,u8 * in_data,u32 in_index,u8 * out_data,u32 out_index)680 int 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 
altera_drscan(struct altera_state * astate,u32 count,u8 * tdi_data,u32 start_index)786 int 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 
altera_swap_dr(struct altera_state * astate,u32 count,u8 * in_data,u32 in_index,u8 * out_data,u32 out_index)878 int 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 
altera_free_buffers(struct altera_state * astate)983 void 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