[PATCH v2 2/2] serial: sc16is7xx: reduce TX refill rate with half-FIFO trigger
From: Paul Mbewe
Date: Mon Sep 28 2026 - 05:51:29 EST
With the TX trigger set to 8 free spaces, THRI is generated roughly once
per 8 transmitted bytes. At 115200 baud 8N1, this corresponds to
approximately 0.7 ms between TX refill events.
Set the TX trigger to 32 free spaces via TLR[3:0]. This makes each refill
larger and reduces the refill rate by about 4x. At 115200 baud 8N1, the
refill cadence becomes approximately 2.8 ms.
The trade-off is that the time-to-empty after THRI asserts is reduced
from 56 to 32 byte times. The fresh-TXLVL refill loop fills the hardware
TX FIFO strictly below whichever trigger is selected. This patch changes
only the refill frequency and the associated latency trade-off.
With the two TX gap fixes applied in both configurations, changing the
trigger from 8 to 32 free spaces produced the following median values
from repeated top snapshots under the same continuous Modbus RTU load.
Each transaction used an 8-byte RX request and a 255-byte TX response,
so the workload was dominated by TX traffic:
trigger=8 trigger=32
SPI IRQ thread CPU 15% 5%
system CPU 44% 29%
idle CPU 40% 52%
one-minute load 2.02 0.99
The datasets contain 547 snapshots with trigger=8 and 535 snapshots with
trigger=32.
Only TLR[3:0] is changed. TLR[7:4] remains zero so the RX trigger retains
its FCR setting. RX trigger tuning may also be useful, but generic RX/TX
trigger configuration is left for follow-up work.
SC16IS7XX_TX_TRIGGER_LEVEL is used for both the programmed TLR value and
the TXLVL refill-loop threshold, keeping the hardware trigger and the
software refill condition synchronized.
TCR/TLR access requires EFR[4] and MCR[2], which are already enabled by
the TCR setup immediately preceding the TLR write.
Reviewed-by: Joachim Knorr <joachim.knorr@xxxxxxxxxxxxxx>
Link: https://lore.kernel.org/linux-serial/20260623112225.82386-3-paultyson.mbewe@xxxxxxxxxxxxxx/
Signed-off-by: Paul Mbewe <paultyson.mbewe@xxxxxxxxxxxxxx>
---
Changes in v2:
- Split the trigger-level change from the stale-TXLVL refill fix
- Reworked the change as a TX load-reduction patch
- Corrected the trigger-level explanation: trigger=32 reduces the
refill rate by about 4x but reduces the time-to-empty after THRI
from 56 to 32 byte times
- Added post-fix A/B CPU and load measurements
- Used one constant for the programmed trigger and refill-loop threshold
- Left the RX trigger unchanged; generic RX/TX trigger configuration
is deferred to follow-up work
drivers/tty/serial/sc16is7xx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c
index 1f7e98c2b570..296079c16fdb 100644
--- a/drivers/tty/serial/sc16is7xx.c
+++ b/drivers/tty/serial/sc16is7xx.c
@@ -216,6 +216,6 @@
#define SC16IS7XX_TLR_RX_TRIGGER(words) ((((words) / 4) & 0x0f) << 4)
-#define SC16IS7XX_TX_TRIGGER_LEVEL 8
+#define SC16IS7XX_TX_TRIGGER_LEVEL 32
/* IOControl register bits (Only 75x/76x) */
#define SC16IS7XX_IOCONTROL_LATCH_BIT BIT(0) /* Enable input latching */
--
2.43.0