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 */ 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} 1022