0001
0002
0003
0004
0005
0006
0007
0008
0009
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
0026
0027
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, IDLE },
0036 { DRSELECT, IDLE },
0037 { IRSELECT, DRCAPTURE },
0038 { DREXIT1, DRSHIFT },
0039 { DREXIT1, DRSHIFT },
0040 { DRUPDATE, DRPAUSE },
0041 { DREXIT2, DRPAUSE },
0042 { DRUPDATE, DRSHIFT },
0043 { DRSELECT, IDLE },
0044 { RESET, IRCAPTURE },
0045 { IREXIT1, IRSHIFT },
0046 { IREXIT1, IRSHIFT },
0047 { IRUPDATE, IRPAUSE },
0048 { IREXIT2, IRPAUSE },
0049 { IRUPDATE, IRSHIFT },
0050 { DRSELECT, IDLE }
0051 };
0052
0053
0054
0055
0056
0057
0058
0059
0060 static const u16 altera_jtag_path_map[16] = {
0061
0062 0x0001, 0xFFFD, 0xFE01, 0xFFE7, 0xFFEF, 0xFF0F, 0xFFBF, 0xFFFF,
0063
0064 0xFEFD, 0x0001, 0xF3FF, 0xF7FF, 0x87FF, 0xDFFF, 0xFFFF, 0x7FFD
0065 };
0066
0067
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
0080 js->jtag_state = ILLEGAL_JTAG_STATE;
0081
0082
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
0277 for (i = 0; i < 5; ++i)
0278 alt_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);
0279
0280
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
0295 altera_jreset_idle(astate);
0296
0297 if (js->jtag_state == state) {
0298
0299
0300
0301
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
0313 tms = (altera_jtag_path_map[js->jtag_state] &
0314 (1 << state))
0315 ? TMS_HIGH : TMS_LOW;
0316
0317
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
0352
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
0368
0369
0370
0371
0372
0373
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
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
0400
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
0445 switch (start_state) {
0446 case 0:
0447 alt_jtag_io(1, 0, 0);
0448 alt_jtag_io(0, 0, 0);
0449 alt_jtag_io(0, 0, 0);
0450 break;
0451
0452 case 1:
0453 alt_jtag_io(1, 0, 0);
0454 alt_jtag_io(1, 0, 0);
0455 alt_jtag_io(1, 0, 0);
0456 alt_jtag_io(0, 0, 0);
0457 alt_jtag_io(0, 0, 0);
0458 break;
0459
0460 case 2:
0461 alt_jtag_io(1, 0, 0);
0462 alt_jtag_io(1, 0, 0);
0463 alt_jtag_io(1, 0, 0);
0464 alt_jtag_io(0, 0, 0);
0465 alt_jtag_io(0, 0, 0);
0466 break;
0467
0468 default:
0469 status = 0;
0470 }
0471
0472 if (status) {
0473
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);
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
0506 switch (start_state) {
0507 case 0:
0508 alt_jtag_io(1, 0, 0);
0509 alt_jtag_io(1, 0, 0);
0510 alt_jtag_io(0, 0, 0);
0511 alt_jtag_io(0, 0, 0);
0512 break;
0513
0514 case 1:
0515 alt_jtag_io(1, 0, 0);
0516 alt_jtag_io(1, 0, 0);
0517 alt_jtag_io(1, 0, 0);
0518 alt_jtag_io(1, 0, 0);
0519 alt_jtag_io(0, 0, 0);
0520 alt_jtag_io(0, 0, 0);
0521 break;
0522
0523 case 2:
0524 alt_jtag_io(1, 0, 0);
0525 alt_jtag_io(1, 0, 0);
0526 alt_jtag_io(1, 0, 0);
0527 alt_jtag_io(1, 0, 0);
0528 alt_jtag_io(0, 0, 0);
0529 alt_jtag_io(0, 0, 0);
0530 break;
0531
0532 default:
0533 status = 0;
0534 }
0535
0536 if (status) {
0537
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);
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
0565
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
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
0651
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
0662 alt_jtag_irscan(astate,
0663 start_code,
0664 shift_count,
0665 js->ir_buffer,
0666 NULL);
0667
0668
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
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
0750
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
0762 alt_jtag_irscan(astate,
0763 start_code,
0764 shift_count,
0765 js->ir_buffer,
0766 js->ir_buffer);
0767
0768
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
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
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
0854
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
0865 alt_jtag_drscan(astate, start_code, shift_count,
0866 js->dr_buffer, NULL);
0867
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
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
0946
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
0958 alt_jtag_drscan(astate,
0959 start_code,
0960 shift_count,
0961 js->dr_buffer,
0962 js->dr_buffer);
0963
0964
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
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
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 }