The dwiic(4) controller on the Ampere eMAG machines has a Tx and Rx
FIFO depth of 16 bytes. The FIFO depth can be read from a register.
However Linux implements logic where (at least for ACPI) the FIFO
depth defaults to 32 bytes and is reduced if a valid (lower) value is
found in the register. So this diff implements that same logic.
Could use some testing on machines with i2c keyboard/mouse/touchpad.
ok?
Index: dev/ic/dwiic.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/dwiic.c,v
retrieving revision 1.5
diff -u -p -r1.5 dwiic.c
--- dev/ic/dwiic.c 16 Jul 2019 19:12:32 -0000 1.5
+++ dev/ic/dwiic.c 5 Aug 2019 20:56:12 -0000
@@ -128,6 +128,8 @@ int
dwiic_init(struct dwiic_softc *sc)
{
uint32_t reg;
+ uint8_t tx_fifo_depth;
+ uint8_t rx_fifo_depth;
/* make sure we're talking to a device we know */
reg = dwiic_read(sc, DW_IC_COMP_TYPE);
@@ -168,6 +170,14 @@ dwiic_init(struct dwiic_softc *sc)
/* FIFO threshold levels */
sc->tx_fifo_depth = 32;
sc->rx_fifo_depth = 32;
+ reg = dwiic_read(sc, DW_IC_COMP_PARAM_1);
+ tx_fifo_depth = DW_IC_TX_FIFO_DEPTH(reg);
+ rx_fifo_depth = DW_IC_RX_FIFO_DEPTH(reg);
+ if (tx_fifo_depth > 1 && tx_fifo_depth < sc->tx_fifo_depth)
+ sc->tx_fifo_depth = tx_fifo_depth;
+ if (rx_fifo_depth > 1 && rx_fifo_depth < sc->rx_fifo_depth)
+ sc->rx_fifo_depth = rx_fifo_depth;
+
dwiic_write(sc, DW_IC_TX_TL, sc->tx_fifo_depth / 2);
dwiic_write(sc, DW_IC_RX_TL, 0);
Index: dev/ic/dwiicreg.h
===================================================================
RCS file: /cvs/src/sys/dev/ic/dwiicreg.h,v
retrieving revision 1.1
diff -u -p -r1.1 dwiicreg.h
--- dev/ic/dwiicreg.h 16 Nov 2017 18:12:27 -0000 1.1
+++ dev/ic/dwiicreg.h 5 Aug 2019 20:56:12 -0000
@@ -49,6 +49,8 @@
#define DW_IC_TX_ABRT_SOURCE 0x80
#define DW_IC_ENABLE_STATUS 0x9c
#define DW_IC_COMP_PARAM_1 0xf4
+#define DW_IC_TX_FIFO_DEPTH(x) ((((x) >> 16) & 0xff) + 1)
+#define DW_IC_RX_FIFO_DEPTH(x) ((((x) >> 8) & 0xff) + 1)
#define DW_IC_COMP_VERSION 0xf8
#define DW_IC_SDA_HOLD_MIN_VERS 0x3131312A
#define DW_IC_COMP_TYPE 0xfc