• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
43 struct altera_jtag_machine {
44 	enum altera_jtag_state tms_high;
45 	enum altera_jtag_state tms_low;
46 };
47 
48 static const struct altera_jtag_machine altera_transitions[] = {
49 	/* RESET     */	{ RESET,	IDLE },
50 	/* IDLE      */	{ DRSELECT,	IDLE },
51 	/* DRSELECT  */	{ IRSELECT,	DRCAPTURE },
52 	/* DRCAPTURE */	{ DREXIT1,	DRSHIFT },
53 	/* DRSHIFT   */	{ DREXIT1,	DRSHIFT },
54 	/* DREXIT1   */	{ DRUPDATE,	DRPAUSE },
55 	/* DRPAUSE   */	{ DREXIT2,	DRPAUSE },
56 	/* DREXIT2   */	{ DRUPDATE,	DRSHIFT },
57 	/* DRUPDATE  */	{ DRSELECT,	IDLE },
58 	/* IRSELECT  */	{ RESET,	IRCAPTURE },
59 	/* IRCAPTURE */	{ IREXIT1,	IRSHIFT },
60 	/* IRSHIFT   */	{ IREXIT1,	IRSHIFT },
61 	/* IREXIT1   */	{ IRUPDATE,	IRPAUSE },
62 	/* IRPAUSE   */	{ IREXIT2,	IRPAUSE },
63 	/* IREXIT2   */	{ IRUPDATE,	IRSHIFT },
64 	/* IRUPDATE  */	{ DRSELECT,	IDLE }
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  */
74 static const u16 altera_jtag_path_map[16] = {
75 	/* RST	RTI	SDRS	CDR	SDR	E1DR	PDR	E2DR */
76 	0x0001,	0xFFFD,	0xFE01,	0xFFE7,	0xFFEF,	0xFF0F,	0xFFBF,	0xFFFF,
77 	/* UDR	SIRS	CIR	SIR	E1IR	PIR	E2IR	UIR */
78 	0xFEFD,	0x0001,	0xF3FF,	0xF7FF,	0x87FF,	0xDFFF,	0xFFFF,	0x7FFD
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 
altera_jinit(struct altera_state * astate)89 int 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 
altera_set_drstop(struct altera_jtag * js,enum altera_jtag_state state)116 int altera_set_drstop(struct altera_jtag *js, enum altera_jtag_state state)
117 {
118 	js->drstop_state = state;
119 
120 	return 0;
121 }
122 
altera_set_irstop(struct altera_jtag * js,enum altera_jtag_state state)123 int altera_set_irstop(struct altera_jtag *js, enum altera_jtag_state state)
124 {
125 	js->irstop_state = state;
126 
127 	return 0;
128 }
129 
altera_set_dr_pre(struct altera_jtag * js,u32 count,u32 start_index,u8 * preamble_data)130 int 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 
altera_set_ir_pre(struct altera_jtag * js,u32 count,u32 start_index,u8 * preamble_data)169 int 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 
altera_set_dr_post(struct altera_jtag * js,u32 count,u32 start_index,u8 * postamble_data)207 int 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 
altera_set_ir_post(struct altera_jtag * js,u32 count,u32 start_index,u8 * postamble_data)247 int 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 
altera_jreset_idle(struct altera_state * astate)286 static 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 
altera_goto_jstate(struct altera_state * astate,enum altera_jtag_state state)299 int 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 
altera_wait_cycles(struct altera_state * astate,s32 cycles,enum altera_jtag_state wait_state)351 int 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 
altera_wait_msecs(struct altera_state * astate,s32 microseconds,enum altera_jtag_state wait_state)378 int 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 
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)404 static 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 
alt_jtag_drscan(struct altera_state * astate,int start_state,int count,u8 * tdi,u8 * tdo)448 static 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 
alt_jtag_irscan(struct altera_state * astate,int start_state,int count,u8 * tdi,u8 * tdo)509 static 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 
altera_extract_target_data(u8 * buffer,u8 * target_data,u32 start_index,u32 preamble_count,u32 target_count)572 static 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 
altera_irscan(struct altera_state * astate,u32 count,u8 * tdi_data,u32 start_index)597 int 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 
altera_swap_ir(struct altera_state * astate,u32 count,u8 * in_data,u32 in_index,u8 * out_data,u32 out_index)694 int 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 
altera_drscan(struct altera_state * astate,u32 count,u8 * tdi_data,u32 start_index)800 int 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 
altera_swap_dr(struct altera_state * astate,u32 count,u8 * in_data,u32 in_index,u8 * out_data,u32 out_index)892 int altera_swap_dr(struct altera_state *astate, u32 count,
893 				u8 *in_data, u32 in_index,
894 				u8 *out_data, u32 out_index)
895 /* Shifts data into data register, capturing output data */
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 
altera_free_buffers(struct altera_state * astate)997 void 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