mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v4 0/2] i2c: Add Synopsys Advanced I2C (DWC_i2c) support for TI TDA54
@ 2026-10-27 11:30 Aniket Limaye
  2026-10-27 11:30 ` [PATCH v4 1/2] dt-bindings: i2c: Add Synopsys DWC_i2c controller Aniket Limaye
  2026-10-27 11:30 ` [PATCH v4 2/2] i2c: Add Synopsys Advanced I2C (DWC_i2c) driver Aniket Limaye
  0 siblings, 2 replies; 4+ messages in thread
From: Aniket Limaye @ 2026-10-27 11:30 UTC (permalink / raw)
  To: Andi Shyti, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Philipp Zabel
  Cc: linux-i2c, devicetree, linux-kernel, Aniket Limaye, lianfeng.ouyang

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>


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-10-27 16:32 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-27 11:30 [PATCH v4 0/2] i2c: Add Synopsys Advanced I2C (DWC_i2c) support for TI TDA54 Aniket Limaye
2026-10-27 11:30 ` [PATCH v4 1/2] dt-bindings: i2c: Add Synopsys DWC_i2c controller Aniket Limaye
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

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®