Skip to content

Commit

Permalink
ig4: Actively use FIFO thresholds
Browse files Browse the repository at this point in the history
Before every wait for FIFO interrupt set how much data/space do we
want to see there.  Previous code was not using it for receive, as
result aggregating interrupts only within processing latency.  The
new code needs only one interrupt per transfer per FIFO length.

On my Dell XPS 13 9310 with iichid(4) touchscreen and touchpad this
reduces the interrupt rate per device down to 2 per sample or 16-20
per second when idle and 120-160 per second when actively touched.

MFC after:	1 month
  • Loading branch information
amotin committed Dec 24, 2023
1 parent dbca442 commit 13037ea
Showing 1 changed file with 17 additions and 20 deletions.
37 changes: 17 additions & 20 deletions sys/dev/ichiic/ig4_iic.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ set_slave_addr(ig4iic_softc_t *sc, uint8_t slave)
/*
* Wait for TXFIFO to drain before disabling the controller.
*/
reg_write(sc, IG4_REG_TX_TL, 0);
wait_intr(sc, IG4_INTR_TX_EMPTY);

set_controller(sc, 0);
Expand Down Expand Up @@ -437,16 +438,20 @@ ig4iic_read(ig4iic_softc_t *sc, uint8_t *buf, uint16_t len,
return (0);

while (received < len) {
/* Ensure we have some free space in TXFIFO */
burst = sc->cfg.txfifo_depth -
(reg_read(sc, IG4_REG_TXFLR) & IG4_FIFOLVL_MASK);
if (burst <= 0) {
reg_write(sc, IG4_REG_TX_TL, IG4_FIFO_LOWAT);
error = wait_intr(sc, IG4_INTR_TX_EMPTY);
if (error)
break;
burst = sc->cfg.txfifo_depth;
burst = sc->cfg.txfifo_depth -
(reg_read(sc, IG4_REG_TXFLR) & IG4_FIFOLVL_MASK);
}
/* Ensure we have enough free space in RXFIFO */
burst = MIN(burst, sc->cfg.rxfifo_depth - lowat);
burst = MIN(burst, sc->cfg.rxfifo_depth -
(requested - received));
target = MIN(requested + burst, (int)len);
while (requested < target) {
cmd = IG4_DATA_COMMAND_RD;
Expand All @@ -463,13 +468,15 @@ ig4iic_read(ig4iic_softc_t *sc, uint8_t *buf, uint16_t len,
lowat = IG4_FIFO_LOWAT;
/* After TXFLR fills up, clear it by reading available data */
while (received < requested - lowat) {
burst = MIN((int)len - received,
burst = MIN(requested - received,
reg_read(sc, IG4_REG_RXFLR) & IG4_FIFOLVL_MASK);
if (burst > 0) {
while (burst--)
buf[received++] = 0xFF &
reg_read(sc, IG4_REG_DATA_CMD);
} else {
reg_write(sc, IG4_REG_RX_TL,
requested - received - lowat - 1);
error = wait_intr(sc, IG4_INTR_RX_FULL);
if (error)
goto out;
Expand All @@ -487,8 +494,7 @@ ig4iic_write(ig4iic_softc_t *sc, uint8_t *buf, uint16_t len,
uint32_t cmd;
int sent = 0;
int burst, target;
int error;
bool lowat_set = false;
int error, lowat;

if (len == 0)
return (0);
Expand All @@ -497,12 +503,7 @@ ig4iic_write(ig4iic_softc_t *sc, uint8_t *buf, uint16_t len,
burst = sc->cfg.txfifo_depth -
(reg_read(sc, IG4_REG_TXFLR) & IG4_FIFOLVL_MASK);
target = MIN(sent + burst, (int)len);
/* Leave some data queued to maintain the hardware pipeline */
if (!lowat_set && target != len) {
lowat_set = true;
reg_write(sc, IG4_REG_TX_TL, IG4_FIFO_LOWAT);
}
while(sent < target) {
while (sent < target) {
cmd = buf[sent];
if (repeated_start && sent == 0)
cmd |= IG4_DATA_RESTART;
Expand All @@ -512,13 +513,16 @@ ig4iic_write(ig4iic_softc_t *sc, uint8_t *buf, uint16_t len,
sent++;
}
if (sent < len) {
if (len - sent <= sc->cfg.txfifo_depth)
lowat = sc->cfg.txfifo_depth - (len - sent);
else
lowat = IG4_FIFO_LOWAT;
reg_write(sc, IG4_REG_TX_TL, lowat);
error = wait_intr(sc, IG4_INTR_TX_EMPTY);
if (error)
break;
}
}
if (lowat_set)
reg_write(sc, IG4_REG_TX_TL, 0);

return (error);
}
Expand Down Expand Up @@ -974,13 +978,6 @@ ig4iic_set_config(ig4iic_softc_t *sc, bool reset)
(sc->cfg.bus_speed & IG4_CTL_SPEED_MASK) == IG4_CTL_SPEED_STD ?
sc->cfg.ss_sda_hold : sc->cfg.fs_sda_hold);

/*
* Use a threshold of 1 so we get interrupted on each character,
* allowing us to use mtx_sleep() in our poll code. Not perfect
* but this is better than using DELAY() for receiving data.
*
* See ig4_var.h for details on interrupt handler synchronization.
*/
reg_write(sc, IG4_REG_RX_TL, 0);
reg_write(sc, IG4_REG_TX_TL, 0);

Expand Down

0 comments on commit 13037ea

Please sign in to comment.