• Michael Zaidman's avatar
    HID: ft260: improve i2c write performance · 6fca5e3f
    Michael Zaidman authored
    The patch improves the I2C write performance by 20 - 30 percent by
    revising the sleep time in the ft260_hid_output_report_check_status()
    in the following ways:
    
    1. Reduce the wait time and start to poll earlier.
    
    Sending a large amount of data at a low I2C clock rate saturates the
    internal FT260 buffer and causes hiccups in status readiness, as shown
    below in the log fragment. Aligning the status check wait time to the
    worst case significantly reduces the write performance.
    
    [Oct22 10:28] ft260_i2c_write: rep 0xd8 addr 0x51 off 0 len 34 d[0] 0x0
    [  +0.005296] ft260_xfer_status: bus_status 0x20, clock 100
    [  +0.013460] ft260_i2c_write: rep 0xd8 addr 0x51 off 0 len 34 d[0] 0x0
    [  +0.003244] ft260_hid_output_report_check_status: wait 1920 usec, len 38
    [  +0.000190] ft260_xfer_status: bus_status 0x40, clock 100
    [  +0.015324] ft260_i2c_write: rep 0xd8 addr 0x51 off 0 len 34 d[0] 0x0
    [  +0.003491] ft260_hid_output_report_check_status: wait 1920 usec, len 38
    [  +0.000202] ft260_xfer_status: bus_status 0x40, clock 100
    [  +0.016047] ft260_i2c_write: rep 0xd8 addr 0x51 off 0 len 34 d[0] 0x0
    [  +0.002768] ft260_hid_output_report_check_status: wait 1920 usec, len 38
    [  +0.000150] ft260_xfer_status: bus_status 0x40, clock 100
    [  +0.011389] ft260_i2c_write: rep 0xd8 addr 0x51 off 0 len 34 d[0] 0x0
    [  +0.003467] ft260_hid_output_report_check_status: wait 1920 usec, len 38
    [  +0.000191] ft260_xfer_status: bus_status 0x41, clock 100
    [  +0.000172] ft260_xfer_status: bus_status 0x41, clock 100
    [  +0.000131] ft260_xfer_status: bus_status 0x41, clock 100
    [  +0.000241] ft260_xfer_status: bus_status 0x41, clock 100
    [  +0.000233] ft260_xfer_status: bus_status 0x41, clock 100
    [  +0.000190] ft260_xfer_status: bus_status 0x41, clock 100
    [  +0.000196] ft260_xfer_status: bus_status 0x40, clock 100
    [  +0.011314] ft260_i2c_write: rep 0xd8 addr 0x51 off 0 len 34 d[0] 0x0
    [  +0.003334] ft260_hid_output_report_check_status: wait 1920 usec, len 38
    [  +0.000227] ft260_xfer_status: bus_status 0x41, clock 100
    [  +0.000204] ft260_xfer_status: bus_status 0x41, clock 100
    [  +0.000198] ft260_xfer_status: bus_status 0x41, clock 100
    [  +0.000147] ft260_xfer_status: bus_status 0x40, clock 100
    [  +0.011060] ft260_i2c_write: rep 0xd8 addr 0x51 off 0 len 34 d[0] 0x0
    
      Before:
        $ sudo ./i2cperf -f 2 -o 2 -s 32 -r 0-0xff 13 0x51 -S
    
          Fill block with increment via i2ctransfer by chunks
          -------------------------------------------------------------------
          data rate(bps)  efficiency(%)  data size(B)  total IOs   IO size(B)
          -------------------------------------------------------------------
          40510           80             256           8           32
    
      After:
        $ sudo ./i2cperf -f 2 -o 2 -s 32 -r 0-0xff 13 0x51 -S
    
          Fill block with increment via i2ctransfer by chunks
          -------------------------------------------------------------------
          data rate(bps)  efficiency(%)  data size(B)  total IOs   IO size(B)
          -------------------------------------------------------------------
          52584           80             256           8           32
    
    2. Do not sleep if the estimated I2C transfer time is below 2 ms since
       the first xfer status query frequently takes around 1.5 ms, and the
       following status queries take about 200us on average. So we usually
       return from the routine after the first 1 - 3 status checks.
    
    [Oct22 11:14] ft260_i2c_write: rep 0xd4 addr 0x51 off 0 len 18 d[0] 0x0
    [  +0.004270] ft260_xfer_status: bus_status 0x20, clock 100
    [  +0.013889] ft260_i2c_write: rep 0xd4 addr 0x51 off 0 len 18 d[0] 0x0
    [  +0.000856] ft260_xfer_status: bus_status 0x41, clock 100
    [  +0.000138] ft260_xfer_status: bus_status 0x40, clock 100
    [  +0.013352] ft260_i2c_write: rep 0xd4 addr 0x51 off 0 len 18 d[0] 0x0
    [  +0.001501] ft260_xfer_status: bus_status 0x41, clock 100
    [  +0.000177] ft260_xfer_status: bus_status 0x40, clock 100
    [  +0.014477] ft260_i2c_write: rep 0xd4 addr 0x51 off 0 len 18 d[0] 0x0
    [  +0.001377] ft260_xfer_status: bus_status 0x41, clock 100
    [  +0.000233] ft260_xfer_status: bus_status 0x41, clock 100
    [  +0.000191] ft260_xfer_status: bus_status 0x40, clock 100
    [  +0.013197] ft260_i2c_write: rep 0xd4 addr 0x51 off 0 len 18 d[0] 0x0
    
      Before:
        $ sudo ./i2cperf -f 2 -o 2 -s 16 -r 0-0xff 13 0x51 -S
    
          Fill block with increment via i2ctransfer by chunks
          -------------------------------------------------------------------
          data rate(bps)  efficiency(%)  data size(B)  total IOs   IO size(B)
          -------------------------------------------------------------------
          28826           73             256           16          16
    
      After:
        $ sudo ./i2cperf -f 2 -o 2 -s 16 -r 0-0xff 13 0x51 -S
    
          Fill block with increment via i2ctransfer by chunks
          -------------------------------------------------------------------
          data rate(bps)  efficiency(%)  data size(B)  total IOs   IO size(B)
          -------------------------------------------------------------------
          45138           73             256           16          16
    Signed-off-by: default avatarMichael Zaidman <michael.zaidman@gmail.com>
    Tested-by: default avatarGuillaume Champagne <champagne.guillaume.c@gmail.com>
    Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
    6fca5e3f
hid-ft260.c 26 KB