Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
   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}