From: Aniket Limaye <a-limaye@ti.com>
To: Andi Shyti <andi.shyti@kernel.org>, Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Philipp Zabel <p.zabel@pengutronix.de>
Cc: <linux-i2c@vger.kernel.org>, <devicetree@vger.kernel.org>,
<linux-kernel@vger.kernel.org>, Aniket Limaye <a-limaye@ti.com>,
<lianfeng.ouyang@starfivetech.com>
Subject: [PATCH v4 0/2] i2c: Add Synopsys Advanced I2C (DWC_i2c) support for TI TDA54
Date: Tue, 27 Oct 2026 17:00:34 +0530 [thread overview]
Message-ID: <20261027-tda54-upstream-i2c-v4-0-ebeeaf87d181@ti.com> (raw)
Add support for the Synopsys Advanced I2C (DWC_i2c [0])
controller present on the TI TDA54 SoC.
This series supports controller mode only: no target mode support. TI
TDA54's DWC_i2c instance does not implement an SMBus block, so the new
driver does not touch any SMBus registers.
* Why a separate driver:
Earlier revisions of this series extended the existing DW_apb_i2c
driver (drivers/i2c/busses/i2c-designware-*) to also handle DWC_i2c,
selecting between the two register layouts at runtime via a new
MODEL_TI_TDA54 flag.
This revision instead adds a new, separate, standalone driver
(drivers/i2c/busses/i2c-dwc-adv.c) and a new binding
(Documentation/devicetree/bindings/i2c/snps,dwc-adv-i2c.yaml), since
DWC_i2c is not register compatible with DW_apb_i2c. Based on review
feedback from previous versions, extending the existing DW_apb_i2c is
not attempted to get away from any hacks and workarounds added there
over the years and to avoid all of the complexity of v3 resulting from
updating each regmap access.
The cost is that the message xfers, abort handling and timing formulas
follow i2c-designware-master.c closely and are duplicated, so fixes
there have to be mirrored by hand. Sharing them would need every
register access, and the interrupt acknowledgment abstracted, with some
possible special casing; same as v3.
* Delta from DW_apb_i2c:
DWC_i2c differs from DW_apb_i2c as follows:
- Register layout (see below): DW_apb_i2c uses a flat set of fixed
register offsets. DWC_i2c groups registers into blocks (OPERATION,
CORE, TIMING, FIFO, INTR, DEBUG, ...) that are discovered at runtime
by walking a chain of block headers, each encoding the length to the
next block and an ID that the driver validates.
- CON register bitfield (see below): DWC_i2c's CON register has no
RESTART_EN or SLAVE_DISABLE bits; restart is implicitly always
enabled in hardware.
- Interrupt acknowledgment: DW_apb_i2c acknowledges interrupts by
reading from N dedicated CLR_* registers. DWC_i2c instead writes a
bitmask to a single CLR_INTR register.
- Shared SS/FS Timing registers: DW_apb_i2c has separate HCNT/LCNT
register pairs for standard and fast speed. DWC_i2c shares a single
HCNT/LCNT pair between the two; whichever value set matches the
configured speed is written at init time.
- Bus capacitance for HS mode: DW_apb_i2c modelled this through DT,
while in DWC_i2c this can be read (100/400pf) from
IC_I2C_CAPABILITIES.IC_CAP_LOADING
- FIFO depth / high-speed mode: DW_apb_i2c has a COMP_PARAM_1
register that can be used to autodetect FIFO depth and high-speed
support. DWC_i2c has no such register; FIFO depth comes from the
compatible string's driver match data instead. High speed mode is
always supported.
Register layout differences from i2c-designware (DW_apb_i2c):
(New driver does not make use of flat map like below, and instead only
stores offsets from respective headers)
1. Reg offsets DW_apb_i2c DWC_i2c (TDA54)
DWC_ADV_IC_I2C_CAPABILITIES NA 0x10
DWC_ADV_IC_I2C_BLOCK_OFFSET NA 0x14
DWC_ADV_IC_I2C_CORE_HEADER NA 0x28
DWC_ADV_IC_TIMING_CTRL_HEADER NA 0x44
DWC_ADV_IC_FIFO_CTRL_HEADER NA 0x7c
DWC_ADV_IC_INTR_DEBUG_HEADER NA 0xbc
DWC_ADV_IC_HWID_HEADER NA 0xf8
[DW_IC_CON] 0x00 0x2c
[DW_IC_TAR] 0x04 0x30
[DW_IC_SAR] 0x08 0x34
[DW_IC_DATA_CMD] 0x10 0x80
[DW_IC_SS_SCL_HCNT] 0x14 0x4c
[DW_IC_SS_SCL_LCNT] 0x18 0x50
[DW_IC_FS_SCL_HCNT] 0x1c NA /* same as SS */
[DW_IC_FS_SCL_LCNT] 0x20 NA /* same as SS */
[DW_IC_HS_SCL_HCNT] 0x24 0x54
[DW_IC_HS_SCL_LCNT] 0x28 0x58
[DW_IC_INTR_STAT] 0x2c 0xc0
[DW_IC_INTR_MASK] 0x30 0xc4
[DW_IC_RAW_INTR_STAT] 0x34 0xc8
[DW_IC_RX_TL] 0x38 0x84
[DW_IC_TX_TL] 0x3c 0x88
[DW_IC_CLR_INTR] 0x40 0xcc
[DW_IC_CLR_RX_UNDER] 0x44 NA
[DW_IC_CLR_RX_OVER] 0x48 NA
[DW_IC_CLR_TX_OVER] 0x4c NA
[DW_IC_CLR_RD_REQ] 0x50 NA
[DW_IC_CLR_TX_ABRT] 0x54 NA
[DW_IC_CLR_RX_DONE] 0x58 NA
[DW_IC_CLR_ACTIVITY] 0x5c NA
[DW_IC_CLR_STOP_DET] 0x60 NA
[DW_IC_CLR_START_DET] 0x64 NA
[DW_IC_CLR_GEN_CALL] 0x68 NA
[DW_IC_ENABLE] 0x6c 0x04
[DW_IC_STATUS] 0x70 0xd8
[DW_IC_TXFLR] 0x74 0xdc
[DW_IC_RXFLR] 0x78 0xe0
[DW_IC_SDA_HOLD] 0x7c 0x5c
[DW_IC_TX_ABRT_SOURCE] 0x80 0xd4
[DW_IC_ENABLE_STATUS] 0x9c 0xd0
[DW_IC_CLR_RESTART_DET] 0xa8 NA
[DW_IC_SMBUS_INTR_STAT] 0xc8 NA
[DW_IC_SMBUS_INTR_MASK] 0xcc NA
[DW_IC_CLR_SMBUS_INTR] 0xd4 NA
[DW_IC_COMP_PARAM_1] 0xf4 NA
[DW_IC_COMP_VERSION] 0xf8 0x100
[DW_IC_COMP_TYPE] 0xfc 0x104
2. DW_IC_CON bitfields:
DW_IC_CON_MASTER BIT(0) BIT(0)
DW_IC_CON_SPEED_STD (1 << 1) (1 << 4)
DW_IC_CON_SPEED_FAST (2 << 1) (2 << 4)
DW_IC_CON_SPEED_HIGH (3 << 1) (3 << 4)
DW_IC_CON_SPEED_MASK GENMASK(2, 1) GENMASK(5, 4)
DW_IC_CON_10BITADDR_SLAVE BIT(3) BIT(8)
DW_IC_CON_10BITADDR_MASTER BIT(4) BIT(9)
DW_IC_CON_RESTART_EN BIT(5) NA
DW_IC_CON_SLAVE_DISABLE BIT(6) NA
DW_IC_CON_STOP_DET_IFADDRESSED BIT(7) BIT(10)
DW_IC_CON_TX_EMPTY_CTRL BIT(8) BIT(11)
DW_IC_CON_RX_FIFO_FULL_HLD_CTRL BIT(9) BIT(12)
DW_IC_CON_BUS_CLEAR_CTRL BIT(11) BIT(14)
The same IP is also used by the StarFive JHB100 SoC [1]. The block
header walk is meant to accommodate such SoC specific layouts, with
their own compatible and match data.
[0]: Synopsys Advanced I2C Controller Reference Manual (Version 2.00a-lca00)
[1]: https://lore.kernel.org/r/20260527085039.44435-1-lianfeng.ouyang@starfivetech.com
Signed-off-by: Aniket Limaye <a-limaye@ti.com>
---
Changes in v4:
- Drop the approach of extending the existing i2c-designware-* driver
with a MODEL_TI_TDA54 variant. Instead, add a new standalone driver
(i2c-dwc-adv.c) and a new binding (snps,dwc-adv-i2c.yaml), since
DWC_i2c is not register compatible with DW_apb_i2c. (Andy Shevchenko)
- Drop the snps,tx-fifo-depth/snps,rx-fifo-depth DT properties from
the new binding; FIFO depth is now tied to the compatible string via
driver match data instead. (Conor Dooley)
- Link to v3: https://lore.kernel.org/r/20260925-tda54-upstream-i2c-v3-0-544d74e992ff@ti.com
Changes in v3:
- [PATCH 2/3] Revert to special handling for the max_register in regmap
for MODEL_AMD_NAVI_GPU instead of unconditionally including
AMD_UCSI_INTR_REG in the legal regmap range. (sashiko)
- Link to v2: https://lore.kernel.org/r/20260925-tda54-upstream-i2c-v2-0-261785e58493@ti.com
Changes in v2:
- Rename compatible/flag: snps,dwc-i2c -> ti,tda54-i2c,
MODEL_DWC_I2C -> MODEL_TI_TDA54.
- Move the Reg ID -> Offset mapping inside the regmap functions such
that existing calls to reg_read/write are unaltered. This does change
the reg_read()/reg_write() functions to take reg IDs as input rather
than their physical offsets, which also requires updates to the
xe_i2c.c driver to handle the same mapping.
- Remove i2c_dwc_has_smbus(); just skip the SMBUS_INTR_MASK write under
MODEL_TI_TDA54.
- Link to v1: https://lore.kernel.org/r/20260919-tda54-upstream-i2c-v1-0-b0b9f77be18b@ti.com
---
Aniket Limaye (2):
dt-bindings: i2c: Add Synopsys DWC_i2c controller
i2c: Add Synopsys Advanced I2C (DWC_i2c) driver
.../devicetree/bindings/i2c/snps,dwc-adv-i2c.yaml | 75 ++
drivers/i2c/busses/Kconfig | 11 +
drivers/i2c/busses/Makefile | 1 +
drivers/i2c/busses/i2c-dwc-adv.c | 1333 ++++++++++++++++++++
4 files changed, 1420 insertions(+)
---
base-commit: 8f7df005a7564bd7ffa75da9c3085d5b996f1e16
change-id: 20260919-tda54-upstream-i2c-d0c67f16b4fc
Best regards,
--
Aniket Limaye <a-limaye@ti.com>
next reply other threads:[~2026-10-27 11:32 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-27 11:30 Aniket Limaye [this message]
2026-10-27 11:30 ` [PATCH v4 1/2] dt-bindings: i2c: Add Synopsys DWC_i2c controller Aniket Limaye
2026-10-27 18:36 ` Krzysztof Kozlowski
2026-10-27 11:30 ` [PATCH v4 2/2] i2c: Add Synopsys Advanced I2C (DWC_i2c) driver Aniket Limaye
2026-10-27 16:32 ` Mark Brown
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261027-tda54-upstream-i2c-v4-0-ebeeaf87d181@ti.com \
--to=a-limaye@ti.com \
--cc=andi.shyti@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=krzk+dt@kernel.org \
--cc=lianfeng.ouyang@starfivetech.com \
--cc=linux-i2c@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=p.zabel@pengutronix.de \
--cc=robh@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®