root/drivers/misc/altera-stapl/altera-jtag.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. altera_jinit
  2. altera_set_drstop
  3. altera_set_irstop
  4. altera_set_dr_pre
  5. altera_set_ir_pre
  6. altera_set_dr_post
  7. altera_set_ir_post
  8. altera_jreset_idle
  9. altera_goto_jstate
  10. altera_wait_cycles
  11. altera_wait_msecs
  12. altera_concatenate_data
  13. alt_jtag_drscan
  14. alt_jtag_irscan
  15. altera_extract_target_data
  16. altera_irscan
  17. altera_swap_ir
  18. altera_drscan
  19. altera_swap_dr
  20. altera_free_buffers

   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  */
  29 struct altera_jtag_machine {
  30         enum altera_jtag_state tms_high;
  31         enum altera_jtag_state tms_low;
  32 };
  33 
  34 static 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  */
  60 static 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 
  75 int 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 
 102 int altera_set_drstop(struct altera_jtag *js, enum altera_jtag_state state)
 103 {
 104         js->drstop_state = state;
 105 
 106         return 0;
 107 }
 108 
 109 int altera_set_irstop(struct altera_jtag *js, enum altera_jtag_state state)
 110 {
 111         js->irstop_state = state;
 112 
 113         return 0;
 114 }
 115 
 116 int 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 
 155 int 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 
 193 int 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 
 233 int 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 
 272 static 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 
 285 int 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 
 337 int 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 
 364 int 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 
 390 static 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 
 434 static 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 
 495 static 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 
 558 static 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 
 583 int 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 
 680 int 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 
 786 int 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 
 878 int 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 
 983 void 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 }

/* [<][>][^][v][top][bottom][index][help] */