@end itemize
 @end deffn
 
+@deffn {Command} {ftdi_tdo_sample_edge} @option{rising}|@option{falling}
+Configure TCK edge at which the adapter samples the value of the TDO signal
+
+Due to signal propagation delays, sampling TDO on rising TCK can become quite
+peculiar at high JTAG clock speeds. However, FTDI chips offer a possiblity to sample
+TDO on falling edge of TCK. With some board/adapter configurations, this may increase
+stability at higher JTAG clocks.
+@itemize @minus
+@item @option{rising}, sample TDO on rising edge of TCK - this is the default
+@item @option{falling}, sample TDO on falling edge of TCK
+@end itemize
+@end deffn
+
 For example adapter definitions, see the configuration files shipped in the
 @file{interface/ftdi} directory.
+
 @end deffn
 
 @deffn {Interface Driver} {remote_bitbang}
 
 #include "mpsse.h"
 
 #define JTAG_MODE (LSB_FIRST | POS_EDGE_IN | NEG_EDGE_OUT)
+#define JTAG_MODE_ALT (LSB_FIRST | NEG_EDGE_IN | NEG_EDGE_OUT)
 #define SWD_MODE (LSB_FIRST | POS_EDGE_IN | NEG_EDGE_OUT)
 
 static char *ftdi_device_desc;
 static char *ftdi_serial;
 static uint8_t ftdi_channel;
+static uint8_t ftdi_jtag_mode = JTAG_MODE;
 
 static bool swd_mode;
 
                0,
                tms_count,
                false,
-               JTAG_MODE);
+               ftdi_jtag_mode);
 }
 
 static int ftdi_speed(int speed)
                return retval;
        }
 
+       if (!swd_mode && speed >= 10000000 && ftdi_jtag_mode != JTAG_MODE_ALT)
+               LOG_INFO("ftdi: if you experience problems at higher adapter clocks, try "
+                        "the command \"ftdi_tdo_sample_edge falling\"");
        return ERROR_OK;
 }
 
        while (i > 0) {
                /* there are no state transitions in this code, so omit state tracking */
                unsigned this_len = i > 7 ? 7 : i;
-               mpsse_clock_tms_cs_out(mpsse_ctx, &zero, 0, this_len, false, JTAG_MODE);
+               mpsse_clock_tms_cs_out(mpsse_ctx, &zero, 0, this_len, false, ftdi_jtag_mode);
                i -= this_len;
        }
 
                0,
                cmd->cmd.tms->num_bits,
                false,
-               JTAG_MODE);
+               ftdi_jtag_mode);
 }
 
 static void ftdi_execute_pathmove(struct jtag_command *cmd)
                                        0,
                                        bit_count,
                                        false,
-                                       JTAG_MODE);
+                                       ftdi_jtag_mode);
                        bit_count = 0;
                }
        }
                                field->in_value,
                                0,
                                field->num_bits - 1,
-                               JTAG_MODE);
+                               ftdi_jtag_mode);
                        uint8_t last_bit = 0;
                        if (field->out_value)
                                bit_copy(&last_bit, 0, field->out_value, field->num_bits - 1, 1);
                                        field->num_bits - 1,
                                        1,
                                        last_bit,
-                                       JTAG_MODE);
+                                       ftdi_jtag_mode);
                        tap_set_state(tap_state_transition(tap_get_state(), 1));
                        mpsse_clock_tms_cs_out(mpsse_ctx,
                                        &tms_bits,
                                        1,
                                        1,
                                        last_bit,
-                                       JTAG_MODE);
+                                       ftdi_jtag_mode);
                        tap_set_state(tap_state_transition(tap_get_state(), 0));
                } else
                        mpsse_clock_data(mpsse_ctx,
                                field->in_value,
                                0,
                                field->num_bits,
-                               JTAG_MODE);
+                               ftdi_jtag_mode);
        }
 
        if (tap_get_state() != tap_get_end_state())
        while (num_cycles > 0) {
                /* there are no state transitions in this code, so omit state tracking */
                unsigned this_len = num_cycles > 7 ? 7 : num_cycles;
-               mpsse_clock_tms_cs_out(mpsse_ctx, &tms, 0, this_len, false, JTAG_MODE);
+               mpsse_clock_tms_cs_out(mpsse_ctx, &tms, 0, this_len, false, ftdi_jtag_mode);
                num_cycles -= this_len;
        }
 
        return ERROR_OK;
 }
 
+COMMAND_HANDLER(ftdi_handle_tdo_sample_edge_command)
+{
+       Jim_Nvp *n;
+       static const Jim_Nvp nvp_ftdi_jtag_modes[] = {
+               { .name = "rising", .value = JTAG_MODE },
+               { .name = "falling", .value = JTAG_MODE_ALT },
+               { .name = NULL, .value = -1 },
+       };
+
+       if (CMD_ARGC > 0) {
+               n = Jim_Nvp_name2value_simple(nvp_ftdi_jtag_modes, CMD_ARGV[0]);
+               if (n->name == NULL)
+                       return ERROR_COMMAND_SYNTAX_ERROR;
+               ftdi_jtag_mode = n->value;
+
+       }
+
+       n = Jim_Nvp_value2name_simple(nvp_ftdi_jtag_modes, ftdi_jtag_mode);
+       command_print(CMD_CTX, "ftdi samples TDO on %s edge of TCK", n->name);
+
+       return ERROR_OK;
+}
+
 static const struct command_registration ftdi_command_handlers[] = {
        {
                .name = "ftdi_device_desc",
                .help = "the vendor ID and product ID of the FTDI device",
                .usage = "(vid pid)* ",
        },
+       {
+               .name = "ftdi_tdo_sample_edge",
+               .handler = &ftdi_handle_tdo_sample_edge_command,
+               .mode = COMMAND_ANY,
+               .help = "set which TCK clock edge is used for sampling TDO "
+                       "- default is rising-edge (Setting to falling-edge may "
+                       "allow signalling speed increase)",
+               .usage = "(rising|falling)",
+       },
        COMMAND_REGISTRATION_DONE
 };