Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * altera-jtag.c
0004  *
0005  * altera FPGA driver
0006  *
0007  * Copyright (C) Altera Corporation 1998-2001
0008  * Copyright (C) 2010 NetUP Inc.
0009  * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
0010  */
0011 
0012 #include <linux/delay.h>
0013 #include <linux/firmware.h>
0014 #include <linux/slab.h>
0015 #include <misc/altera.h>
0016 #include "altera-exprt.h"
0017 #include "altera-jtag.h"
0018 
0019 #define alt_jtag_io(a, b, c)\
0020         astate->config->jtag_io(astate->config->dev, a, b, c);
0021 
0022 #define alt_malloc(a)   kzalloc(a, GFP_KERNEL);
0023 
0024 /*
0025  * This structure shows, for each JTAG state, which state is reached after
0026  * a single TCK clock cycle with TMS high or TMS low, respectively.  This
0027  * describes all possible state transitions in the JTAG state machine.
0028  */
0029 struct altera_jtag_machine {
0030     enum altera_jtag_state tms_high;
0031     enum altera_jtag_state tms_low;
0032 };
0033 
0034 static const struct altera_jtag_machine altera_transitions[] = {
0035     /* RESET     */ { RESET,    IDLE },
0036     /* IDLE      */ { DRSELECT, IDLE },
0037     /* DRSELECT  */ { IRSELECT, DRCAPTURE },
0038     /* DRCAPTURE */ { DREXIT1,  DRSHIFT },
0039     /* DRSHIFT   */ { DREXIT1,  DRSHIFT },
0040     /* DREXIT1   */ { DRUPDATE, DRPAUSE },
0041     /* DRPAUSE   */ { DREXIT2,  DRPAUSE },
0042     /* DREXIT2   */ { DRUPDATE, DRSHIFT },
0043     /* DRUPDATE  */ { DRSELECT, IDLE },
0044     /* IRSELECT  */ { RESET,    IRCAPTURE },
0045     /* IRCAPTURE */ { IREXIT1,  IRSHIFT },
0046     /* IRSHIFT   */ { IREXIT1,  IRSHIFT },
0047     /* IREXIT1   */ { IRUPDATE, IRPAUSE },
0048     /* IRPAUSE   */ { IREXIT2,  IRPAUSE },
0049     /* IREXIT2   */ { IRUPDATE, IRSHIFT },
0050     /* IRUPDATE  */ { DRSELECT, IDLE }
0051 };
0052 
0053 /*
0054  * This table contains the TMS value to be used to take the NEXT STEP on
0055  * the path to the desired state.  The array index is the current state,
0056  * and the bit position is the desired endstate.  To find out which state
0057  * is used as the intermediate state, look up the TMS value in the
0058  * altera_transitions[] table.
0059  */
0060 static const u16 altera_jtag_path_map[16] = {
0061     /* RST  RTI SDRS    CDR SDR E1DR    PDR E2DR */
0062     0x0001, 0xFFFD, 0xFE01, 0xFFE7, 0xFFEF, 0xFF0F, 0xFFBF, 0xFFFF,
0063     /* UDR  SIRS    CIR SIR E1IR    PIR E2IR    UIR */
0064     0xFEFD, 0x0001, 0xF3FF, 0xF7FF, 0x87FF, 0xDFFF, 0xFFFF, 0x7FFD
0065 };
0066 
0067 /* Flag bits for alt_jtag_io() function */
0068 #define TMS_HIGH   1
0069 #define TMS_LOW    0
0070 #define TDI_HIGH   1
0071 #define TDI_LOW    0
0072 #define READ_TDO   1
0073 #define IGNORE_TDO 0
0074 
0075 int altera_jinit(struct altera_state *astate)
0076 {
0077     struct altera_jtag *js = &astate->js;
0078 
0079     /* initial JTAG state is unknown */
0080     js->jtag_state = ILLEGAL_JTAG_STATE;
0081 
0082     /* initialize to default state */
0083     js->drstop_state = IDLE;
0084     js->irstop_state = IDLE;
0085     js->dr_pre  = 0;
0086     js->dr_post = 0;
0087     js->ir_pre  = 0;
0088     js->ir_post = 0;
0089     js->dr_length    = 0;
0090     js->ir_length    = 0;
0091 
0092     js->dr_pre_data  = NULL;
0093     js->dr_post_data = NULL;
0094     js->ir_pre_data  = NULL;
0095     js->ir_post_data = NULL;
0096     js->dr_buffer    = NULL;
0097     js->ir_buffer    = NULL;
0098 
0099     return 0;
0100 }
0101 
0102 int altera_set_drstop(struct altera_jtag *js, enum altera_jtag_state state)
0103 {
0104     js->drstop_state = state;
0105 
0106     return 0;
0107 }
0108 
0109 int altera_set_irstop(struct altera_jtag *js, enum altera_jtag_state state)
0110 {
0111     js->irstop_state = state;
0112 
0113     return 0;
0114 }
0115 
0116 int altera_set_dr_pre(struct altera_jtag *js,
0117                 u32 count, u32 start_index,
0118                 u8 *preamble_data)
0119 {
0120     int status = 0;
0121     u32 i;
0122     u32 j;
0123 
0124     if (count > js->dr_pre) {
0125         kfree(js->dr_pre_data);
0126         js->dr_pre_data = (u8 *)alt_malloc((count + 7) >> 3);
0127         if (js->dr_pre_data == NULL)
0128             status = -ENOMEM;
0129         else
0130             js->dr_pre = count;
0131     } else
0132         js->dr_pre = count;
0133 
0134     if (status == 0) {
0135         for (i = 0; i < count; ++i) {
0136             j = i + start_index;
0137 
0138             if (preamble_data == NULL)
0139                 js->dr_pre_data[i >> 3] |= (1 << (i & 7));
0140             else {
0141                 if (preamble_data[j >> 3] & (1 << (j & 7)))
0142                     js->dr_pre_data[i >> 3] |=
0143                             (1 << (i & 7));
0144                 else
0145                     js->dr_pre_data[i >> 3] &=
0146                             ~(u32)(1 << (i & 7));
0147 
0148             }
0149         }
0150     }
0151 
0152     return status;
0153 }
0154 
0155 int altera_set_ir_pre(struct altera_jtag *js, u32 count, u32 start_index,
0156                             u8 *preamble_data)
0157 {
0158     int status = 0;
0159     u32 i;
0160     u32 j;
0161 
0162     if (count > js->ir_pre) {
0163         kfree(js->ir_pre_data);
0164         js->ir_pre_data = (u8 *)alt_malloc((count + 7) >> 3);
0165         if (js->ir_pre_data == NULL)
0166             status = -ENOMEM;
0167         else
0168             js->ir_pre = count;
0169 
0170     } else
0171         js->ir_pre = count;
0172 
0173     if (status == 0) {
0174         for (i = 0; i < count; ++i) {
0175             j = i + start_index;
0176             if (preamble_data == NULL)
0177                 js->ir_pre_data[i >> 3] |= (1 << (i & 7));
0178             else {
0179                 if (preamble_data[j >> 3] & (1 << (j & 7)))
0180                     js->ir_pre_data[i >> 3] |=
0181                             (1 << (i & 7));
0182                 else
0183                     js->ir_pre_data[i >> 3] &=
0184                             ~(u32)(1 << (i & 7));
0185 
0186             }
0187         }
0188     }
0189 
0190     return status;
0191 }
0192 
0193 int altera_set_dr_post(struct altera_jtag *js, u32 count, u32 start_index,
0194                         u8 *postamble_data)
0195 {
0196     int status = 0;
0197     u32 i;
0198     u32 j;
0199 
0200     if (count > js->dr_post) {
0201         kfree(js->dr_post_data);
0202         js->dr_post_data = (u8 *)alt_malloc((count + 7) >> 3);
0203 
0204         if (js->dr_post_data == NULL)
0205             status = -ENOMEM;
0206         else
0207             js->dr_post = count;
0208 
0209     } else
0210         js->dr_post = count;
0211 
0212     if (status == 0) {
0213         for (i = 0; i < count; ++i) {
0214             j = i + start_index;
0215 
0216             if (postamble_data == NULL)
0217                 js->dr_post_data[i >> 3] |= (1 << (i & 7));
0218             else {
0219                 if (postamble_data[j >> 3] & (1 << (j & 7)))
0220                     js->dr_post_data[i >> 3] |=
0221                                 (1 << (i & 7));
0222                 else
0223                     js->dr_post_data[i >> 3] &=
0224                         ~(u32)(1 << (i & 7));
0225 
0226             }
0227         }
0228     }
0229 
0230     return status;
0231 }
0232 
0233 int altera_set_ir_post(struct altera_jtag *js, u32 count, u32 start_index,
0234                         u8 *postamble_data)
0235 {
0236     int status = 0;
0237     u32 i;
0238     u32 j;
0239 
0240     if (count > js->ir_post) {
0241         kfree(js->ir_post_data);
0242         js->ir_post_data = (u8 *)alt_malloc((count + 7) >> 3);
0243         if (js->ir_post_data == NULL)
0244             status = -ENOMEM;
0245         else
0246             js->ir_post = count;
0247 
0248     } else
0249         js->ir_post = count;
0250 
0251     if (status != 0)
0252         return status;
0253 
0254     for (i = 0; i < count; ++i) {
0255         j = i + start_index;
0256 
0257         if (postamble_data == NULL)
0258             js->ir_post_data[i >> 3] |= (1 << (i & 7));
0259         else {
0260             if (postamble_data[j >> 3] & (1 << (j & 7)))
0261                 js->ir_post_data[i >> 3] |= (1 << (i & 7));
0262             else
0263                 js->ir_post_data[i >> 3] &=
0264                     ~(u32)(1 << (i & 7));
0265 
0266         }
0267     }
0268 
0269     return status;
0270 }
0271 
0272 static void altera_jreset_idle(struct altera_state *astate)
0273 {
0274     struct altera_jtag *js = &astate->js;
0275     int i;
0276     /* Go to Test Logic Reset (no matter what the starting state may be) */
0277     for (i = 0; i < 5; ++i)
0278         alt_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);
0279 
0280     /* Now step to Run Test / Idle */
0281     alt_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
0282     js->jtag_state = IDLE;
0283 }
0284 
0285 int altera_goto_jstate(struct altera_state *astate,
0286                     enum altera_jtag_state state)
0287 {
0288     struct altera_jtag *js = &astate->js;
0289     int tms;
0290     int count = 0;
0291     int status = 0;
0292 
0293     if (js->jtag_state == ILLEGAL_JTAG_STATE)
0294         /* initialize JTAG chain to known state */
0295         altera_jreset_idle(astate);
0296 
0297     if (js->jtag_state == state) {
0298         /*
0299          * We are already in the desired state.
0300          * If it is a stable state, loop here.
0301          * Otherwise do nothing (no clock cycles).
0302          */
0303         if ((state == IDLE) || (state == DRSHIFT) ||
0304             (state == DRPAUSE) || (state == IRSHIFT) ||
0305                 (state == IRPAUSE)) {
0306             alt_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
0307         } else if (state == RESET)
0308             alt_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);
0309 
0310     } else {
0311         while ((js->jtag_state != state) && (count < 9)) {
0312             /* Get TMS value to take a step toward desired state */
0313             tms = (altera_jtag_path_map[js->jtag_state] &
0314                             (1 << state))
0315                             ? TMS_HIGH : TMS_LOW;
0316 
0317             /* Take a step */
0318             alt_jtag_io(tms, TDI_LOW, IGNORE_TDO);
0319 
0320             if (tms)
0321                 js->jtag_state =
0322                     altera_transitions[js->jtag_state].tms_high;
0323             else
0324                 js->jtag_state =
0325                     altera_transitions[js->jtag_state].tms_low;
0326 
0327             ++count;
0328         }
0329     }
0330 
0331     if (js->jtag_state != state)
0332         status = -EREMOTEIO;
0333 
0334     return status;
0335 }
0336 
0337 int altera_wait_cycles(struct altera_state *astate,
0338                     s32 cycles,
0339                     enum altera_jtag_state wait_state)
0340 {
0341     struct altera_jtag *js = &astate->js;
0342     int tms;
0343     s32 count;
0344     int status = 0;
0345 
0346     if (js->jtag_state != wait_state)
0347         status = altera_goto_jstate(astate, wait_state);
0348 
0349     if (status == 0) {
0350         /*
0351          * Set TMS high to loop in RESET state
0352          * Set TMS low to loop in any other stable state
0353          */
0354         tms = (wait_state == RESET) ? TMS_HIGH : TMS_LOW;
0355 
0356         for (count = 0L; count < cycles; count++)
0357             alt_jtag_io(tms, TDI_LOW, IGNORE_TDO);
0358 
0359     }
0360 
0361     return status;
0362 }
0363 
0364 int altera_wait_msecs(struct altera_state *astate,
0365             s32 microseconds, enum altera_jtag_state wait_state)
0366 /*
0367  * Causes JTAG hardware to sit in the specified stable
0368  * state for the specified duration of real time.  If
0369  * no JTAG operations have been performed yet, then only
0370  * a delay is performed.  This permits the WAIT USECS
0371  * statement to be used in VECTOR programs without causing
0372  * any JTAG operations.
0373  * Returns 0 for success, else appropriate error code.
0374  */
0375 {
0376     struct altera_jtag *js = &astate->js;
0377     int status = 0;
0378 
0379     if ((js->jtag_state != ILLEGAL_JTAG_STATE) &&
0380         (js->jtag_state != wait_state))
0381         status = altera_goto_jstate(astate, wait_state);
0382 
0383     if (status == 0)
0384         /* Wait for specified time interval */
0385         udelay(microseconds);
0386 
0387     return status;
0388 }
0389 
0390 static void altera_concatenate_data(u8 *buffer,
0391                 u8 *preamble_data,
0392                 u32 preamble_count,
0393                 u8 *target_data,
0394                 u32 start_index,
0395                 u32 target_count,
0396                 u8 *postamble_data,
0397                 u32 postamble_count)
0398 /*
0399  * Copies preamble data, target data, and postamble data
0400  * into one buffer for IR or DR scans.
0401  */
0402 {
0403     u32 i, j, k;
0404 
0405     for (i = 0L; i < preamble_count; ++i) {
0406         if (preamble_data[i >> 3L] & (1L << (i & 7L)))
0407             buffer[i >> 3L] |= (1L << (i & 7L));
0408         else
0409             buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));
0410 
0411     }
0412 
0413     j = start_index;
0414     k = preamble_count + target_count;
0415     for (; i < k; ++i, ++j) {
0416         if (target_data[j >> 3L] & (1L << (j & 7L)))
0417             buffer[i >> 3L] |= (1L << (i & 7L));
0418         else
0419             buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));
0420 
0421     }
0422 
0423     j = 0L;
0424     k = preamble_count + target_count + postamble_count;
0425     for (; i < k; ++i, ++j) {
0426         if (postamble_data[j >> 3L] & (1L << (j & 7L)))
0427             buffer[i >> 3L] |= (1L << (i & 7L));
0428         else
0429             buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));
0430 
0431     }
0432 }
0433 
0434 static int alt_jtag_drscan(struct altera_state *astate,
0435             int start_state,
0436             int count,
0437             u8 *tdi,
0438             u8 *tdo)
0439 {
0440     int i = 0;
0441     int tdo_bit = 0;
0442     int status = 1;
0443 
0444     /* First go to DRSHIFT state */
0445     switch (start_state) {
0446     case 0:                     /* IDLE */
0447         alt_jtag_io(1, 0, 0);   /* DRSELECT */
0448         alt_jtag_io(0, 0, 0);   /* DRCAPTURE */
0449         alt_jtag_io(0, 0, 0);   /* DRSHIFT */
0450         break;
0451 
0452     case 1:                     /* DRPAUSE */
0453         alt_jtag_io(1, 0, 0);   /* DREXIT2 */
0454         alt_jtag_io(1, 0, 0);   /* DRUPDATE */
0455         alt_jtag_io(1, 0, 0);   /* DRSELECT */
0456         alt_jtag_io(0, 0, 0);   /* DRCAPTURE */
0457         alt_jtag_io(0, 0, 0);   /* DRSHIFT */
0458         break;
0459 
0460     case 2:                     /* IRPAUSE */
0461         alt_jtag_io(1, 0, 0);   /* IREXIT2 */
0462         alt_jtag_io(1, 0, 0);   /* IRUPDATE */
0463         alt_jtag_io(1, 0, 0);   /* DRSELECT */
0464         alt_jtag_io(0, 0, 0);   /* DRCAPTURE */
0465         alt_jtag_io(0, 0, 0);   /* DRSHIFT */
0466         break;
0467 
0468     default:
0469         status = 0;
0470     }
0471 
0472     if (status) {
0473         /* loop in the SHIFT-DR state */
0474         for (i = 0; i < count; i++) {
0475             tdo_bit = alt_jtag_io(
0476                     (i == count - 1),
0477                     tdi[i >> 3] & (1 << (i & 7)),
0478                     (tdo != NULL));
0479 
0480             if (tdo != NULL) {
0481                 if (tdo_bit)
0482                     tdo[i >> 3] |= (1 << (i & 7));
0483                 else
0484                     tdo[i >> 3] &= ~(u32)(1 << (i & 7));
0485 
0486             }
0487         }
0488 
0489         alt_jtag_io(0, 0, 0);   /* DRPAUSE */
0490     }
0491 
0492     return status;
0493 }
0494 
0495 static int alt_jtag_irscan(struct altera_state *astate,
0496             int start_state,
0497             int count,
0498             u8 *tdi,
0499             u8 *tdo)
0500 {
0501     int i = 0;
0502     int tdo_bit = 0;
0503     int status = 1;
0504 
0505     /* First go to IRSHIFT state */
0506     switch (start_state) {
0507     case 0:                     /* IDLE */
0508         alt_jtag_io(1, 0, 0);   /* DRSELECT */
0509         alt_jtag_io(1, 0, 0);   /* IRSELECT */
0510         alt_jtag_io(0, 0, 0);   /* IRCAPTURE */
0511         alt_jtag_io(0, 0, 0);   /* IRSHIFT */
0512         break;
0513 
0514     case 1:                     /* DRPAUSE */
0515         alt_jtag_io(1, 0, 0);   /* DREXIT2 */
0516         alt_jtag_io(1, 0, 0);   /* DRUPDATE */
0517         alt_jtag_io(1, 0, 0);   /* DRSELECT */
0518         alt_jtag_io(1, 0, 0);   /* IRSELECT */
0519         alt_jtag_io(0, 0, 0);   /* IRCAPTURE */
0520         alt_jtag_io(0, 0, 0);   /* IRSHIFT */
0521         break;
0522 
0523     case 2:                     /* IRPAUSE */
0524         alt_jtag_io(1, 0, 0);   /* IREXIT2 */
0525         alt_jtag_io(1, 0, 0);   /* IRUPDATE */
0526         alt_jtag_io(1, 0, 0);   /* DRSELECT */
0527         alt_jtag_io(1, 0, 0);   /* IRSELECT */
0528         alt_jtag_io(0, 0, 0);   /* IRCAPTURE */
0529         alt_jtag_io(0, 0, 0);   /* IRSHIFT */
0530         break;
0531 
0532     default:
0533         status = 0;
0534     }
0535 
0536     if (status) {
0537         /* loop in the SHIFT-IR state */
0538         for (i = 0; i < count; i++) {
0539             tdo_bit = alt_jtag_io(
0540                       (i == count - 1),
0541                       tdi[i >> 3] & (1 << (i & 7)),
0542                       (tdo != NULL));
0543             if (tdo != NULL) {
0544                 if (tdo_bit)
0545                     tdo[i >> 3] |= (1 << (i & 7));
0546                 else
0547                     tdo[i >> 3] &= ~(u32)(1 << (i & 7));
0548 
0549             }
0550         }
0551 
0552         alt_jtag_io(0, 0, 0);   /* IRPAUSE */
0553     }
0554 
0555     return status;
0556 }
0557 
0558 static void altera_extract_target_data(u8 *buffer,
0559                 u8 *target_data,
0560                 u32 start_index,
0561                 u32 preamble_count,
0562                 u32 target_count)
0563 /*
0564  * Copies target data from scan buffer, filtering out
0565  * preamble and postamble data.
0566  */
0567 {
0568     u32 i;
0569     u32 j;
0570     u32 k;
0571 
0572     j = preamble_count;
0573     k = start_index + target_count;
0574     for (i = start_index; i < k; ++i, ++j) {
0575         if (buffer[j >> 3] & (1 << (j & 7)))
0576             target_data[i >> 3] |= (1 << (i & 7));
0577         else
0578             target_data[i >> 3] &= ~(u32)(1 << (i & 7));
0579 
0580     }
0581 }
0582 
0583 int altera_irscan(struct altera_state *astate,
0584                 u32 count,
0585                 u8 *tdi_data,
0586                 u32 start_index)
0587 /* Shifts data into instruction register */
0588 {
0589     struct altera_jtag *js = &astate->js;
0590     int start_code = 0;
0591     u32 alloc_chars = 0;
0592     u32 shift_count = js->ir_pre + count + js->ir_post;
0593     int status = 0;
0594     enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
0595 
0596     switch (js->jtag_state) {
0597     case ILLEGAL_JTAG_STATE:
0598     case RESET:
0599     case IDLE:
0600         start_code = 0;
0601         start_state = IDLE;
0602         break;
0603 
0604     case DRSELECT:
0605     case DRCAPTURE:
0606     case DRSHIFT:
0607     case DREXIT1:
0608     case DRPAUSE:
0609     case DREXIT2:
0610     case DRUPDATE:
0611         start_code = 1;
0612         start_state = DRPAUSE;
0613         break;
0614 
0615     case IRSELECT:
0616     case IRCAPTURE:
0617     case IRSHIFT:
0618     case IREXIT1:
0619     case IRPAUSE:
0620     case IREXIT2:
0621     case IRUPDATE:
0622         start_code = 2;
0623         start_state = IRPAUSE;
0624         break;
0625 
0626     default:
0627         status = -EREMOTEIO;
0628         break;
0629     }
0630 
0631     if (status == 0)
0632         if (js->jtag_state != start_state)
0633             status = altera_goto_jstate(astate, start_state);
0634 
0635     if (status == 0) {
0636         if (shift_count > js->ir_length) {
0637             alloc_chars = (shift_count + 7) >> 3;
0638             kfree(js->ir_buffer);
0639             js->ir_buffer = (u8 *)alt_malloc(alloc_chars);
0640             if (js->ir_buffer == NULL)
0641                 status = -ENOMEM;
0642             else
0643                 js->ir_length = alloc_chars * 8;
0644 
0645         }
0646     }
0647 
0648     if (status == 0) {
0649         /*
0650          * Copy preamble data, IR data,
0651          * and postamble data into a buffer
0652          */
0653         altera_concatenate_data(js->ir_buffer,
0654                     js->ir_pre_data,
0655                     js->ir_pre,
0656                     tdi_data,
0657                     start_index,
0658                     count,
0659                     js->ir_post_data,
0660                     js->ir_post);
0661         /* Do the IRSCAN */
0662         alt_jtag_irscan(astate,
0663                 start_code,
0664                 shift_count,
0665                 js->ir_buffer,
0666                 NULL);
0667 
0668         /* alt_jtag_irscan() always ends in IRPAUSE state */
0669         js->jtag_state = IRPAUSE;
0670     }
0671 
0672     if (status == 0)
0673         if (js->irstop_state != IRPAUSE)
0674             status = altera_goto_jstate(astate, js->irstop_state);
0675 
0676 
0677     return status;
0678 }
0679 
0680 int altera_swap_ir(struct altera_state *astate,
0681                 u32 count,
0682                 u8 *in_data,
0683                 u32 in_index,
0684                 u8 *out_data,
0685                 u32 out_index)
0686 /* Shifts data into instruction register, capturing output data */
0687 {
0688     struct altera_jtag *js = &astate->js;
0689     int start_code = 0;
0690     u32 alloc_chars = 0;
0691     u32 shift_count = js->ir_pre + count + js->ir_post;
0692     int status = 0;
0693     enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
0694 
0695     switch (js->jtag_state) {
0696     case ILLEGAL_JTAG_STATE:
0697     case RESET:
0698     case IDLE:
0699         start_code = 0;
0700         start_state = IDLE;
0701         break;
0702 
0703     case DRSELECT:
0704     case DRCAPTURE:
0705     case DRSHIFT:
0706     case DREXIT1:
0707     case DRPAUSE:
0708     case DREXIT2:
0709     case DRUPDATE:
0710         start_code = 1;
0711         start_state = DRPAUSE;
0712         break;
0713 
0714     case IRSELECT:
0715     case IRCAPTURE:
0716     case IRSHIFT:
0717     case IREXIT1:
0718     case IRPAUSE:
0719     case IREXIT2:
0720     case IRUPDATE:
0721         start_code = 2;
0722         start_state = IRPAUSE;
0723         break;
0724 
0725     default:
0726         status = -EREMOTEIO;
0727         break;
0728     }
0729 
0730     if (status == 0)
0731         if (js->jtag_state != start_state)
0732             status = altera_goto_jstate(astate, start_state);
0733 
0734     if (status == 0) {
0735         if (shift_count > js->ir_length) {
0736             alloc_chars = (shift_count + 7) >> 3;
0737             kfree(js->ir_buffer);
0738             js->ir_buffer = (u8 *)alt_malloc(alloc_chars);
0739             if (js->ir_buffer == NULL)
0740                 status = -ENOMEM;
0741             else
0742                 js->ir_length = alloc_chars * 8;
0743 
0744         }
0745     }
0746 
0747     if (status == 0) {
0748         /*
0749          * Copy preamble data, IR data,
0750          * and postamble data into a buffer
0751          */
0752         altera_concatenate_data(js->ir_buffer,
0753                     js->ir_pre_data,
0754                     js->ir_pre,
0755                     in_data,
0756                     in_index,
0757                     count,
0758                     js->ir_post_data,
0759                     js->ir_post);
0760 
0761         /* Do the IRSCAN */
0762         alt_jtag_irscan(astate,
0763                 start_code,
0764                 shift_count,
0765                 js->ir_buffer,
0766                 js->ir_buffer);
0767 
0768         /* alt_jtag_irscan() always ends in IRPAUSE state */
0769         js->jtag_state = IRPAUSE;
0770     }
0771 
0772     if (status == 0)
0773         if (js->irstop_state != IRPAUSE)
0774             status = altera_goto_jstate(astate, js->irstop_state);
0775 
0776 
0777     if (status == 0)
0778         /* Now extract the returned data from the buffer */
0779         altera_extract_target_data(js->ir_buffer,
0780                     out_data, out_index,
0781                     js->ir_pre, count);
0782 
0783     return status;
0784 }
0785 
0786 int altera_drscan(struct altera_state *astate,
0787                 u32 count,
0788                 u8 *tdi_data,
0789                 u32 start_index)
0790 /* Shifts data into data register (ignoring output data) */
0791 {
0792     struct altera_jtag *js = &astate->js;
0793     int start_code = 0;
0794     u32 alloc_chars = 0;
0795     u32 shift_count = js->dr_pre + count + js->dr_post;
0796     int status = 0;
0797     enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
0798 
0799     switch (js->jtag_state) {
0800     case ILLEGAL_JTAG_STATE:
0801     case RESET:
0802     case IDLE:
0803         start_code = 0;
0804         start_state = IDLE;
0805         break;
0806 
0807     case DRSELECT:
0808     case DRCAPTURE:
0809     case DRSHIFT:
0810     case DREXIT1:
0811     case DRPAUSE:
0812     case DREXIT2:
0813     case DRUPDATE:
0814         start_code = 1;
0815         start_state = DRPAUSE;
0816         break;
0817 
0818     case IRSELECT:
0819     case IRCAPTURE:
0820     case IRSHIFT:
0821     case IREXIT1:
0822     case IRPAUSE:
0823     case IREXIT2:
0824     case IRUPDATE:
0825         start_code = 2;
0826         start_state = IRPAUSE;
0827         break;
0828 
0829     default:
0830         status = -EREMOTEIO;
0831         break;
0832     }
0833 
0834     if (status == 0)
0835         if (js->jtag_state != start_state)
0836             status = altera_goto_jstate(astate, start_state);
0837 
0838     if (status == 0) {
0839         if (shift_count > js->dr_length) {
0840             alloc_chars = (shift_count + 7) >> 3;
0841             kfree(js->dr_buffer);
0842             js->dr_buffer = (u8 *)alt_malloc(alloc_chars);
0843             if (js->dr_buffer == NULL)
0844                 status = -ENOMEM;
0845             else
0846                 js->dr_length = alloc_chars * 8;
0847 
0848         }
0849     }
0850 
0851     if (status == 0) {
0852         /*
0853          * Copy preamble data, DR data,
0854          * and postamble data into a buffer
0855          */
0856         altera_concatenate_data(js->dr_buffer,
0857                     js->dr_pre_data,
0858                     js->dr_pre,
0859                     tdi_data,
0860                     start_index,
0861                     count,
0862                     js->dr_post_data,
0863                     js->dr_post);
0864         /* Do the DRSCAN */
0865         alt_jtag_drscan(astate, start_code, shift_count,
0866                 js->dr_buffer, NULL);
0867         /* alt_jtag_drscan() always ends in DRPAUSE state */
0868         js->jtag_state = DRPAUSE;
0869     }
0870 
0871     if (status == 0)
0872         if (js->drstop_state != DRPAUSE)
0873             status = altera_goto_jstate(astate, js->drstop_state);
0874 
0875     return status;
0876 }
0877 
0878 int altera_swap_dr(struct altera_state *astate, u32 count,
0879                 u8 *in_data, u32 in_index,
0880                 u8 *out_data, u32 out_index)
0881 /* Shifts data into data register, capturing output data */
0882 {
0883     struct altera_jtag *js = &astate->js;
0884     int start_code = 0;
0885     u32 alloc_chars = 0;
0886     u32 shift_count = js->dr_pre + count + js->dr_post;
0887     int status = 0;
0888     enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
0889 
0890     switch (js->jtag_state) {
0891     case ILLEGAL_JTAG_STATE:
0892     case RESET:
0893     case IDLE:
0894         start_code = 0;
0895         start_state = IDLE;
0896         break;
0897 
0898     case DRSELECT:
0899     case DRCAPTURE:
0900     case DRSHIFT:
0901     case DREXIT1:
0902     case DRPAUSE:
0903     case DREXIT2:
0904     case DRUPDATE:
0905         start_code = 1;
0906         start_state = DRPAUSE;
0907         break;
0908 
0909     case IRSELECT:
0910     case IRCAPTURE:
0911     case IRSHIFT:
0912     case IREXIT1:
0913     case IRPAUSE:
0914     case IREXIT2:
0915     case IRUPDATE:
0916         start_code = 2;
0917         start_state = IRPAUSE;
0918         break;
0919 
0920     default:
0921         status = -EREMOTEIO;
0922         break;
0923     }
0924 
0925     if (status == 0)
0926         if (js->jtag_state != start_state)
0927             status = altera_goto_jstate(astate, start_state);
0928 
0929     if (status == 0) {
0930         if (shift_count > js->dr_length) {
0931             alloc_chars = (shift_count + 7) >> 3;
0932             kfree(js->dr_buffer);
0933             js->dr_buffer = (u8 *)alt_malloc(alloc_chars);
0934 
0935             if (js->dr_buffer == NULL)
0936                 status = -ENOMEM;
0937             else
0938                 js->dr_length = alloc_chars * 8;
0939 
0940         }
0941     }
0942 
0943     if (status == 0) {
0944         /*
0945          * Copy preamble data, DR data,
0946          * and postamble data into a buffer
0947          */
0948         altera_concatenate_data(js->dr_buffer,
0949                 js->dr_pre_data,
0950                 js->dr_pre,
0951                 in_data,
0952                 in_index,
0953                 count,
0954                 js->dr_post_data,
0955                 js->dr_post);
0956 
0957         /* Do the DRSCAN */
0958         alt_jtag_drscan(astate,
0959                 start_code,
0960                 shift_count,
0961                 js->dr_buffer,
0962                 js->dr_buffer);
0963 
0964         /* alt_jtag_drscan() always ends in DRPAUSE state */
0965         js->jtag_state = DRPAUSE;
0966     }
0967 
0968     if (status == 0)
0969         if (js->drstop_state != DRPAUSE)
0970             status = altera_goto_jstate(astate, js->drstop_state);
0971 
0972     if (status == 0)
0973         /* Now extract the returned data from the buffer */
0974         altera_extract_target_data(js->dr_buffer,
0975                     out_data,
0976                     out_index,
0977                     js->dr_pre,
0978                     count);
0979 
0980     return status;
0981 }
0982 
0983 void altera_free_buffers(struct altera_state *astate)
0984 {
0985     struct altera_jtag *js = &astate->js;
0986     /* If the JTAG interface was used, reset it to TLR */
0987     if (js->jtag_state != ILLEGAL_JTAG_STATE)
0988         altera_jreset_idle(astate);
0989 
0990     kfree(js->dr_pre_data);
0991     js->dr_pre_data = NULL;
0992 
0993     kfree(js->dr_post_data);
0994     js->dr_post_data = NULL;
0995 
0996     kfree(js->dr_buffer);
0997     js->dr_buffer = NULL;
0998 
0999     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 }