[RFC PATCH] i2c: designware: Enable SAR in slave mode for Multiple SAR controllers
Umesh Kumar <[email protected]> Tue, 4 Aug 2026 09:48:42 +0530
| Newsgroups | org.kernel.vger.linux-i2c,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
DesignWare controllers synthesised with the Multiple SAR feature (e.g. Marvell CN20K) only acknowledge traffic to the primary slave address (IC_SAR) when IC_ENABLE[19] (SAR_EN) is set. The slave enable path writes only IC_ENABLE[0], so on such controllers the target never ACKs its address and a remote master cannot reach it. Set SAR_EN together with ENABLE when entering slave mode. The bit is reserved (and ignored) on single-SAR controllers, so existing users are unaffected. Signed-off-by: Umesh Kumar <[email protected]> --- RFC note: On our multi-SAR CN20K the slave only ACKs with IC_ENABLE[19] set. Existing single-SAR users work without it, and the bit is reserved there, so I've written it unconditionally. Would you prefer this gated behind a per-device capability flag instead? The CN20K PCI device enablement (which would set such a flag) can follow as a separate series. drivers/i2c/busses/i2c-designware-common.c | 9 ++++++++- drivers/i2c/busses/i2c-designware-core.h | 6 ++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-designware-common.c b/drivers/i2c/busses/i2c-designware-common.c index 4dc57fd56170..b6f3d71cf268 100644 --- a/drivers/i2c/busses/i2c-designware-common.c +++ b/drivers/i2c/busses/i2c-designware-common.c @@ -374,7 +374,14 @@ static void i2c_dw_configure_mode(struct dw_i2c_dev *dev, int mode) regmap_write(dev->map, DW_IC_CON, dev->slave_cfg); regmap_write(dev->map, DW_IC_SAR, dev->slave->addr); regmap_write(dev->map, DW_IC_INTR_MASK, DW_IC_INTR_SLAVE_MASK); - __i2c_dw_enable(dev); + /* + * Controllers synthesised with the Multiple SAR feature only + * acknowledge traffic to IC_SAR when SAR_EN is set; a plain + * enable is not enough. The bit is reserved (ignored) on + * single-SAR controllers. + */ + regmap_write(dev->map, DW_IC_ENABLE, + DW_IC_ENABLE_ENABLE | DW_IC_ENABLE_SAR_EN); break; default: WARN(1, "Invalid mode %d\n", mode); diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index 9d8d104cc391..35eaf2d7404f 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -125,6 +125,12 @@ #define DW_IC_ENABLE_ENABLE BIT(0) #define DW_IC_ENABLE_ABORT BIT(1) +/* + * On controllers synthesised with the Multiple SAR feature (e.g. Marvell + * CN20K), the primary slave address register (IC_SAR) only acknowledges bus + * traffic when this bit is set. It is reserved on single-SAR controllers. + */ +#define DW_IC_ENABLE_SAR_EN BIT(19) #define DW_IC_STATUS_ACTIVITY BIT(0) #define DW_IC_STATUS_TFE BIT(2) -- 2.43.0