altera-jtag.c (21450B)
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}