Skip to content

Conversation

ziuziakowska
Copy link

@ziuziakowska ziuziakowska commented Aug 28, 2025

This PR implements the Opentitan Earlgrey 1.0.0 I2C controller, based on the current Darjeeling I2C implementation which to my understanding is similar to Earlgrey ES.

The main differences are a different register interface with some moved fields, most FIFO overflow interrupts are replaced with threshold interrupts, and FIFO thresholds can be any amount of bytes.

Unsupported or partially implemented features:

  • Only 7-bit addressing is supported, with no address bit masking. (TARGET_ID only supports ADDRESS0 with MASK0 == 0x7f)
  • Loopback mode (CTRL.LLPBK) is unsupported.
  • Timing-related registers or physical layer controls are unimplemented:
    • TIMING0-TIMING4 registers. (besides the changes in earlgrey-9.2.0 that at least check the values are within spec.)
    • OVRD to manually drive SDA/SCL. VAL, ACQ_FIFO_NEXT_DATA.
    • Clock stretching controls. (HOST_TIMEOUT_CTRL, TARGET_TIMEOUT_CTRL, TARGET_ACK_CTRL, HOST_NACK_HANDLER_TIMEOUT)

@ziuziakowska ziuziakowska force-pushed the ot_i2c branch 2 times, most recently from 873b2e4 to 5d61b85 Compare August 28, 2025 09:28
@AlexJones0
Copy link

AlexJones0 commented Aug 28, 2025

I've not had a chance to look in detail yet, but one quick high-level comment: as I understand, although the current QEMU Darjeeling I2C implementation (i.e. what is already in ot_i2c_dj.c) is similar to Earlgrey ES, the current OpenTitan Darjeeling I2C (i.e. what we want to emulate) should be similar to the current Earlgrey I2C.

So, I think in this PR it would be appropriate to just rename ot_i2c_dj to ot_i2c and use it for both tops, as I don't think there are any notable differences for emulation at the moment, so duplicating the device and having 2 I2C implementations will just be harder to maintain I think.

Aside: there do seem to have been 1 or 2 RTL Changes since earlgrey_1.0.0 was taken, but only to hardware internals like e.g. the DMA interface - these could be added to Darjeeling if necessary with versioning later on, like is done in e.g. the pwrmgr.

@AlexJones0
Copy link

Also another note: if you could add a commit that quickly updates the status of I2C in docs/opentitan/earlgrey.md that would be great. It doesn't have to be super descriptive, just mention any notable supported/missing features as is done for the other IP.

@loiclefort
Copy link

loiclefort commented Aug 28, 2025

I think in this PR it would be appropriate to just rename ot_i2c_dj to ot_i2c and use it for both tops

Agreed. Earlgrey and Darjeeling should share the same I2C implementation.

@ziuziakowska ziuziakowska changed the base branch from ot-earlgrey_1.0.0-9.2.0 to ot-earlgrey-9.2.0 August 29, 2025 09:54
@ziuziakowska ziuziakowska force-pushed the ot_i2c branch 8 times, most recently from bb95860 to 713c8c8 Compare August 29, 2025 13:31
@ziuziakowska ziuziakowska marked this pull request as ready for review August 29, 2025 13:46
Copy link

@engdoreis engdoreis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @ziuziakowska for this PR.
I'm not very familiar with the code base, so I'll leave in deth reviews for Alex and Loïc.
The only thing that I beleive that would make sense to change is to squash the commits:

  • "[ot] hw/riscv: ot_earlgrey: copy ot_i2c_dj into ot_i2c, add ot_i2c to eg"
  • "[ot] hw: riscv,opentitan: replace ot_i2c_dj with ot_i2c"

I would also suggest running clang-format/tidy on every commit.

@ziuziakowska ziuziakowska changed the title DRAFT: Opentitan EG 1.0.0 I2C implementation Opentitan EG 1.0.0 I2C implementation Sep 1, 2025
@ziuziakowska ziuziakowska marked this pull request as draft September 3, 2025 11:18
@ziuziakowska ziuziakowska force-pushed the ot_i2c branch 2 times, most recently from 5c49a29 to 743d259 Compare September 3, 2025 13:09
Copy link

@rivos-eblot rivos-eblot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: I'm not familiar enough with the I2C implementation to provide feedback about HW emulation, so comments are mostly about generic QEMU OT idioms.

@rivos-eblot
Copy link

I feel like I'm lacking the background to comment on the correct build configuration options so I'll leave that to @rivos-eblot, but I've left some comments on both the HW emulation and general QEMU idioms.

Build config seems ok to me, thanks for the changes.

Signed-off-by: Alice Ziuziakowska <a.ziuziakowska@lowrisc.org>
taken from `hw/top_earlgrey/sw/autogen/top_earlgrey.h`

Signed-off-by: Alice Ziuziakowska <a.ziuziakowska@lowrisc.org>
Copy link

@AlexJones0 AlexJones0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the changes - I'm happy to merge this after my comment is addressed.

@rivos-eblot is this okay to merge for you?
(edit: nevermind, I can't because of the requested changes anyway 😅)

Copy link

@rivos-eblot rivos-eblot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@rivos-eblot
Copy link

@rivos-eblot is this okay to merge for you? (edit: nevermind, I can't because of the requested changes anyway 😅)
Yes thanks.

@rivos-eblot rivos-eblot self-requested a review September 5, 2025 07:53
This updates the interrupts and registers for the I2C block from the
earlgrey-es interface to earlgrey 1.0.0.

`FIFO_STATUS` has been split off into `HOST_FIFO_STATUS` and
`TARGET_FIFO_STATUS`, and some fields from `FIFO_CTRL` have been moved
to the new `HOST_FIFO_CONFIG` and `TARGET_FIFO_CONFIG`.

The remaining newly added registers are not yet implemented.

Interrupts are now caused by exceeding a per-fifo threshold instead on
overflow.

Signed-off-by: Alice Ziuziakowska <a.ziuziakowska@lowrisc.org>
Signed-off-by: Alice Ziuziakowska <a.ziuziakowska@lowrisc.org>
This commit makes each I2C controller create its own I2C bus using its
`ot_id` in the bus name ('ot-i2c0`, `ot-i2c1`, `ot-i2c2`).
Previously, each instantiation would overwrite the previous and leave
only one `ot-i2c` bus.

Signed-off-by: Alice Ziuziakowska <a.ziuziakowska@lowrisc.org>
This commit changes the names of
`ot_i2c_{host,target}_get_{rx,tx}_threshold` to use the names of the
FIFOs it is checking. It also adds
`ot_i2c_{fmt,acq,rx,tx}_threshold_intr` functions to compare against the
threshold to determine if the corresponding level interrupt should be
asserted, as some FIFOs assert the interrupt below their threshold and
others above.

Signed-off-by: Alice Ziuziakowska <a.ziuziakowska@lowrisc.org>
With the removal of the `FMTILVL` and `RXILVL` fields, this register is
now write-only.

Signed-off-by: Alice Ziuziakowska <a.ziuziakowska@lowrisc.org>
These registers contain latched event bits that are RW1C. All bits must
be cleared to deassert the interrupt.

Signed-off-by: Alice Ziuziakowska <a.ziuziakowska@lowrisc.org>
Signed-off-by: Alice Ziuziakowska <a.ziuziakowska@lowrisc.org>
This implements the `NAKOK` field when sending bytes in host mode.

If `NAKOK` is set, then the current byte in a write transaction
will not cause a controller halt interrupt if the byte is not ACK'd.
The behaviour if READB and NAKOK are both set is unspecified in the docs
so this is rejected.

Since this flag needs to be stored for each byte, the FMT FIFO is
upgraded from a `Fifo8` to a `OtFifo32` to store the extra bit.
This bit is not sent over I2C as it only affects controller interrupts.

Signed-off-by: Alice Ziuziakowska <a.ziuziakowska@lowrisc.org>
The I2C_NACK event seems to be unreachable as we do not use
`i2c_send_async`, `i2c_send` returns a NACK by return value, `i2c_recv`
is infallible, and we ACK every byte we receive in target mode so we
cannot receive a byte that was NACK'd.

Signed-off-by: Alice Ziuziakowska <a.ziuziakowska@lowrisc.org>
Signed-off-by: Alice Ziuziakowska <a.ziuziakowska@lowrisc.org>
Default depth value for this FIFO is 268.

See `hw/ip/i2c/data/i2c.hjson` in Opentitan.

Signed-off-by: Alice Ziuziakowska <a.ziuziakowska@lowrisc.org>
@AlexJones0 AlexJones0 merged commit e0d1af7 into lowRISC:ot-earlgrey-9.2.0 Sep 8, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants