This is an automated email from Gerrit. "Tomas Vanek <van...@fbl.cz>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/7218
-- gerrit commit 660576fd51f5dd9d57e46a79462a1fbeafb90e5f Author: Tomas Vanek <van...@fbl.cz> Date: Wed Sep 21 14:26:07 2022 +0200 target/adi_v5_swd: optimize sequences in swd_connect_multidrop() swd_connect_multidrop() sent DORMANT_TO_SWD and called swd_multidrop_select_inner(). DORMANT_TO_SWD sequence ends with a LINE_RESET sequence. swd_multidrop_select_inner() sent LINE_RESET sequence again. It was useless in this case. Move LINE_RESET sending to swd_multidrop_select(). swd_connect_multidrop() now sends just one LINE_RESET (the one contained in DORMANT_TO_SWD). Change-Id: Iba21620f6a9680793208bf398960ed0eb59df3b1 Signed-off-by: Tomas Vanek <van...@fbl.cz> diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c index aea730d4d1..c948852977 100644 --- a/src/target/adi_v5_swd.c +++ b/src/target/adi_v5_swd.c @@ -176,21 +176,6 @@ 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) return retval; @@ -209,6 +194,9 @@ static int swd_multidrop_select_inner(struct adiv5_dap *dap, uint32_t *dpidr_ptr return retval; } + /* Set dap->select to DP_SELECT_INVALID because all field of the register + * except DPBANKSEL are unknown after line reset. + */ dap->select = DP_SELECT_INVALID; retval = swd_queue_dp_read_inner(dap, DP_DLPIDR, &dlpidr); @@ -260,6 +248,19 @@ static int swd_multidrop_select(struct adiv5_dap *dap) for (unsigned int retry = 0; ; retry++) { bool clear_sticky = retry > 0; + 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. + */ + dap->select = 0; + retval = swd_multidrop_select_inner(dap, NULL, NULL, clear_sticky); if (retval == ERROR_OK) break; @@ -295,6 +296,19 @@ static int swd_connect_multidrop(struct adiv5_dap *dap) dap_invalidate_cache(dap); swd_multidrop_selected_dap = NULL; + /* The sequence DORMANT_TO_SWD ends with a SWD line reset sequence. + * 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. + */ + dap->select = 0; + retval = swd_multidrop_select_inner(dap, &dpidr, &dlpidr, true); if (retval == ERROR_OK) break; --