From 53b58b0881cdbcd903dbcd8fd765ebfb0ec56042 Mon Sep 17 00:00:00 2001 From: Eero Nurkkala Date: Tue, 9 May 2023 11:23:06 +0300 Subject: [PATCH] risc-v/mpfs: i2c: fix an FPGA known issue This fixes the following issue: - After sending the address, the driver writes an extra zero Without this patch, the extra write causes an extra ACK that would terminate the sequence prematurely. This is observed as data read corruption. With this fix, the condition is detected precisely. That being the case, the sequence is continued with a repeated start, after which the read continues normally. Signed-off-by: Eero Nurkkala --- arch/risc-v/src/mpfs/mpfs_i2c.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/arch/risc-v/src/mpfs/mpfs_i2c.c b/arch/risc-v/src/mpfs/mpfs_i2c.c index 44c53fda1c..59093559a5 100644 --- a/arch/risc-v/src/mpfs/mpfs_i2c.c +++ b/arch/risc-v/src/mpfs/mpfs_i2c.c @@ -459,7 +459,26 @@ static int mpfs_i2c_irq(int cpuint, void *context, void *arg) { /* Send stop condition */ - modifyreg32(MPFS_I2C_CTRL, 0, MPFS_I2C_CTRL_STO_MASK); + if (priv->fpga && (priv->rx_idx == 0 && priv->rx_size > 0)) + { + /* This is a known bug: FPGA IP sends data twice after + * sending the address occasionally. Instead of sending + * STOP, send repeated start instead. + */ + + modifyreg32(MPFS_I2C_CTRL, MPFS_I2C_CTRL_SI_MASK, 0); + clear_irq = 0u; + modifyreg32(MPFS_I2C_CTRL, 0, MPFS_I2C_CTRL_STA_MASK); + + /* Jump to the next message */ + + priv->msgid++; + } + else + { + modifyreg32(MPFS_I2C_CTRL, 0, MPFS_I2C_CTRL_STO_MASK); + } + priv->status = MPFS_I2C_SUCCESS; } break;