PageRenderTime 67ms CodeModel.GetById 33ms app.highlight 29ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/staging/altera-stapl/altera-jtag.c

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