diff options
author | Ernesto Corona <ernesto.corona@intel.com> | 2021-08-25 00:38:03 +0300 |
---|---|---|
committer | Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com> | 2021-10-20 01:10:40 +0300 |
commit | 787a61dc545bcfadd2db9c3ef96c0bcee1e66f21 (patch) | |
tree | 65a95b21e8c2ff9a641804efb20785986691423f | |
parent | c36397853b3e04df252868e4c2e3be4f96019e3c (diff) | |
download | linux-787a61dc545bcfadd2db9c3ef96c0bcee1e66f21.tar.xz |
ASD Fix AST26xx HW mode end tap state support
Previous this change we send JTAG state machine to RTI in all shifts
that end state was EXIT1IR/EXIT1DR. With this rule we were able to
guarantee a smooth chain transition in HW mode (chain is expected to
be in RTI after chain has been selected). However, there were
uncovered cases such as Go to Ex1IR and then Go to ShfDR which
doesn't expect to visit RTI.
With this change AST26xx shift behavior in HW mode will be more
accurate to what it is being requested. JTAG state machine will
remain in EXIT1IR/EXIT1DR when those end states are being sent to
the aspeed_jtag_xfer_hw2 driver function.
It is now expected that ASD application calculates the right end
state and send either EXIT1IR, EXIT1DR, RTI or PAUSEDR to control
shift operations and JTAG state transitions in HW mode.
Additionally aspeed_jtag_set_tap_state_hw2() function was updated to
handle go to RTI from EXIT1 included in two different network
packets.
Tested:
Using Software, HW1 and HW2 modes:
ASD Sanity ended successfully.
Signed-off-by: Ernesto Corona <ernesto.corona@intel.com>
Change-Id: Ic49b0ce26c49d08e806c29e5ae72a4b3b7e68553
-rw-r--r-- | drivers/jtag/jtag-aspeed.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/jtag/jtag-aspeed.c b/drivers/jtag/jtag-aspeed.c index 727aa0a37c68..f9a5f4d95710 100644 --- a/drivers/jtag/jtag-aspeed.c +++ b/drivers/jtag/jtag-aspeed.c @@ -663,7 +663,13 @@ static void aspeed_jtag_set_tap_state_hw2(struct aspeed_jtag *aspeed_jtag, ASPEED_JTAG_GBLCTRL); udelay(AST26XX_JTAG_CTRL_UDELAY); aspeed_jtag->current_state = JTAG_STATE_TLRESET; - return; + } else if (tapstate->endstate == JTAG_STATE_IDLE && + aspeed_jtag->current_state != JTAG_STATE_IDLE) { + /* Always go to RTI, do not wait for shift operation */ + aspeed_jtag_set_tap_state(aspeed_jtag, + aspeed_jtag->current_state, + JTAG_STATE_IDLE); + aspeed_jtag->current_state = JTAG_STATE_IDLE; } } @@ -1066,6 +1072,7 @@ static int aspeed_jtag_xfer_hw2(struct aspeed_jtag *aspeed_jtag, u32 reg_val; enum jtag_tapstate shift; enum jtag_tapstate exit; + enum jtag_tapstate exitx; enum jtag_tapstate pause; enum jtag_tapstate endstate; u32 start_shift; @@ -1077,11 +1084,13 @@ static int aspeed_jtag_xfer_hw2(struct aspeed_jtag *aspeed_jtag, shift = JTAG_STATE_SHIFTIR; pause = JTAG_STATE_PAUSEIR; exit = JTAG_STATE_EXIT1IR; + exitx = JTAG_STATE_EXIT1DR; } else { data_reg = ASPEED_JTAG_SHDATA; shift = JTAG_STATE_SHIFTDR; pause = JTAG_STATE_PAUSEDR; exit = JTAG_STATE_EXIT1DR; + exitx = JTAG_STATE_EXIT1IR; } #ifdef DEBUG_JTAG dev_dbg(aspeed_jtag->dev, @@ -1097,7 +1106,8 @@ static int aspeed_jtag_xfer_hw2(struct aspeed_jtag *aspeed_jtag, start_shift = 0; } else if (aspeed_jtag->current_state == JTAG_STATE_IDLE || aspeed_jtag->current_state == JTAG_STATE_TLRESET || - aspeed_jtag->current_state == pause) { + aspeed_jtag->current_state == pause || + aspeed_jtag->current_state == exitx) { start_shift = ASPEED_JTAG_SHCTRL_START_SHIFT; } else { return -EINVAL; @@ -1129,7 +1139,7 @@ static int aspeed_jtag_xfer_hw2(struct aspeed_jtag *aspeed_jtag, endstate = shift; } } else if (xfer->endstate == exit) { - endstate = JTAG_STATE_IDLE; + endstate = exit; end_shift = ASPEED_JTAG_SHCTRL_END_SHIFT; } else if (xfer->endstate == JTAG_STATE_IDLE) { endstate = JTAG_STATE_IDLE; |