summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErnesto Corona <ernesto.corona@intel.com>2021-08-25 00:38:03 +0300
committerJae Hyun Yoo <jae.hyun.yoo@linux.intel.com>2021-10-20 01:10:40 +0300
commit787a61dc545bcfadd2db9c3ef96c0bcee1e66f21 (patch)
tree65a95b21e8c2ff9a641804efb20785986691423f
parentc36397853b3e04df252868e4c2e3be4f96019e3c (diff)
downloadlinux-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.c16
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;