| From d8a25af6715965ff2ac1e3c9646c48e75d297a97 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 25 Sep 2025 10:02:27 +0800 |
| Subject: i2c: spacemit: disable SDA glitch fix to avoid restart delay |
| |
| From: Troy Mitchell <troy.mitchell@linux.spacemit.com> |
| |
| [ Upstream commit 11f40684ccd84e792eced110f0a5d3d6adbdf90d ] |
| |
| The K1 I2C controller has an SDA glitch fix that introduces a small |
| delay on restart signals. While this feature can suppress glitches |
| on SDA when SCL = 0, it also delays the restart signal, which may |
| cause unexpected behavior in some transfers. |
| |
| The glitch itself does not affect normal I2C operation, because |
| the I2C specification allows SDA to change while SCL is low. |
| |
| To ensure correct transmission for every message, we disable the |
| SDA glitch fix by setting the RCR.SDA_GLITCH_NOFIX bit during |
| initialization. |
| |
| This guarantees that restarts are issued promptly without |
| unintended delays. |
| |
| Fixes: 5ea558473fa31 ("i2c: spacemit: add support for SpacemiT K1 SoC") |
| Reviewed-by: Aurelien Jarno <aurelien@aurel32.net> |
| Signed-off-by: Troy Mitchell <troy.mitchell@linux.spacemit.com> |
| Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/i2c/busses/i2c-k1.c | 11 +++++++++++ |
| 1 file changed, 11 insertions(+) |
| |
| diff --git a/drivers/i2c/busses/i2c-k1.c b/drivers/i2c/busses/i2c-k1.c |
| index 84f132d0504dc..9bf9f01aa68bd 100644 |
| --- a/drivers/i2c/busses/i2c-k1.c |
| +++ b/drivers/i2c/busses/i2c-k1.c |
| @@ -14,6 +14,7 @@ |
| #define SPACEMIT_ICR 0x0 /* Control register */ |
| #define SPACEMIT_ISR 0x4 /* Status register */ |
| #define SPACEMIT_IDBR 0xc /* Data buffer register */ |
| +#define SPACEMIT_IRCR 0x18 /* Reset cycle counter */ |
| #define SPACEMIT_IBMR 0x1c /* Bus monitor register */ |
| |
| /* SPACEMIT_ICR register fields */ |
| @@ -76,6 +77,8 @@ |
| SPACEMIT_SR_GCAD | SPACEMIT_SR_IRF | SPACEMIT_SR_ITE | \ |
| SPACEMIT_SR_ALD) |
| |
| +#define SPACEMIT_RCR_SDA_GLITCH_NOFIX BIT(7) /* bypass the SDA glitch fix */ |
| + |
| /* SPACEMIT_IBMR register fields */ |
| #define SPACEMIT_BMR_SDA BIT(0) /* SDA line level */ |
| #define SPACEMIT_BMR_SCL BIT(1) /* SCL line level */ |
| @@ -237,6 +240,14 @@ static void spacemit_i2c_init(struct spacemit_i2c_dev *i2c) |
| val |= SPACEMIT_CR_MSDE | SPACEMIT_CR_MSDIE; |
| |
| writel(val, i2c->base + SPACEMIT_ICR); |
| + |
| + /* |
| + * The glitch fix in the K1 I2C controller introduces a delay |
| + * on restart signals, so we disable the fix here. |
| + */ |
| + val = readl(i2c->base + SPACEMIT_IRCR); |
| + val |= SPACEMIT_RCR_SDA_GLITCH_NOFIX; |
| + writel(val, i2c->base + SPACEMIT_IRCR); |
| } |
| |
| static inline void |
| -- |
| 2.51.0 |
| |