target/adi_v5_swd: fix SWD multidrop
Implementation of ADI v6 introduced banking of DP reg 0.
The accompanying change preventing DP SELECT write before
DP IDR read during connect was added to swd_connect_single() only.
Unchanged swd_connect_multidrop() / swd_multidrop_select_inner()
was broken as it emited DP SELECT and put DP to protocol error state.
Copy dap->select handling to swd_multidrop_select_inner().
Fixes: 72fb88613f
(adiv6: add low level swd transport)
Change-Id: I514cd6d9ae2ba97ce3657b459df22638c278a0b1
Signed-off-by: Tomas Vanek <vanekt@fbl.cz>
Reviewed-on: https://review.openocd.org/c/openocd/+/7213
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-by: Jonathan Bell <jonathan@raspberrypi.com>
This commit is contained in:
parent
60abbda8bc
commit
b2f6b23117
|
@ -177,6 +177,19 @@ static int swd_multidrop_select_inner(struct adiv5_dap *dap, uint32_t *dpidr_ptr
|
|||
assert(dap_is_multidrop(dap));
|
||||
|
||||
swd_send_sequence(dap, LINE_RESET);
|
||||
/* From ARM IHI 0074C ADIv6.0, chapter B4.3.3 "Connection and line reset
|
||||
* sequence":
|
||||
* - line reset sets DP_SELECT_DPBANK to zero;
|
||||
* - read of DP_DPIDR takes the connection out of reset;
|
||||
* - write of DP_TARGETSEL keeps the connection in reset;
|
||||
* - other accesses return protocol error (SWDIO not driven by target).
|
||||
*
|
||||
* Read DP_DPIDR to get out of reset. Initialize dap->select to zero to
|
||||
* skip the write to DP_SELECT, avoiding the protocol error. Set again
|
||||
* dap->select to DP_SELECT_INVALID because the rest of the register is
|
||||
* unknown after line reset.
|
||||
*/
|
||||
dap->select = 0;
|
||||
|
||||
retval = swd_queue_dp_write_inner(dap, DP_TARGETSEL, dap->multidrop_targetsel);
|
||||
if (retval != ERROR_OK)
|
||||
|
@ -196,6 +209,8 @@ static int swd_multidrop_select_inner(struct adiv5_dap *dap, uint32_t *dpidr_ptr
|
|||
return retval;
|
||||
}
|
||||
|
||||
dap->select = DP_SELECT_INVALID;
|
||||
|
||||
retval = swd_queue_dp_read_inner(dap, DP_DLPIDR, &dlpidr);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
@ -342,6 +357,7 @@ static int swd_connect_single(struct adiv5_dap *dap)
|
|||
|
||||
dap->switch_through_dormant = !dap->switch_through_dormant;
|
||||
} while (timeval_ms() < timeout);
|
||||
|
||||
dap->select = DP_SELECT_INVALID;
|
||||
|
||||
if (retval != ERROR_OK) {
|
||||
|
|
Loading…
Reference in New Issue