Skip to content

Conversation

@mausys
Copy link
Contributor

@mausys mausys commented Oct 10, 2025

The Xilinx Zynq 7000 I2C controller has the following bugs:

  • completion indication is not given to the driver at the end of a read/receive transfer with HOLD bit set.
  • Invalid read transaction are generated on the bus when HW timeout condition occurs with HOLD bit set.
  • If the delay between address register write and control register write in cdns_i2c_mrecv function is more, the xfer size register rolls over and controller is stuck.

As a result of the above, this patch disallows message transfers with a repeated start condition following a read operation. Also disables interrupts between the address register write and control register write during message reception, to prevent transfer size register rollover.

Copy link
Contributor

@teburd teburd left a comment

Choose a reason for hiding this comment

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

Because this is a hardware errata fix with a software workaround not every instance of this IP should have to pay the cost of it.

All changes should be wrapped up in ifdef's based on a driver Kconfig for this fix (not specifically tied to xilinx), then selected by the zynq7000 when you build with that particular part.

@mausys
Copy link
Contributor Author

mausys commented Oct 10, 2025

In preparation for #90071, I’ve copied the relevant code from the Linux driver. However, I don’t currently have an I2C device to test the errata scenarios.

Regarding the MMU configuration, should this be handled within the drivers themselves, or added to soc.c? Alternatively, would it make sense to use a 1MB L1 section mapping in soc.c to cover the majority of the peripheral registers?

@teburd
Copy link
Contributor

teburd commented Oct 10, 2025

In preparation for #90071, I’ve copied the relevant code from the Linux driver. However, I don’t currently have an I2C device to test the errata scenarios.

You've copied this from Linux, a GPLv2 project to this Apache licensed project? I do hope you mean by this you were inspired by the ideas and logic and didn't directly copy paste code snippets.

Regarding the MMU configuration, should this be handled within the drivers themselves, or added to soc.c? Alternatively, would it make sense to use a 1MB L1 section mapping in soc.c to cover the majority of the peripheral registers?

Maybe @henrikbrixandersen would have a better answer for this as I know he's used this part with Zephyr.

@mausys
Copy link
Contributor Author

mausys commented Oct 10, 2025

Sorry, yes I mean inspired, like the rest of the driver code :).

The Xilinx Zynq 7000 I2C controller has the following bugs: - completion indication is not given to the driver at the end of a read/receive transfer with HOLD bit set. - Invalid read transaction are generated on the bus when HW timeout condition occurs with HOLD bit set. - If the delay between address register write and control register write in cdns_i2c_mrecv function is more, the xfer size register rolls over and controller is stuck. As a result of the above, this patch disallows message transfers with a repeated start condition following a read operation. Also disables interrupts between the address register write and control register write during message reception, to prevent transfer size register rollover. Signed-off-by: Simon Maurer <mail@maurer.systems>
@mausys mausys force-pushed the cadence_i2c_quirk branch from d21ae50 to 71f22b1 Compare October 10, 2025 14:02
@mausys mausys requested a review from teburd October 10, 2025 16:12
@robhancocksed
Copy link
Contributor

In Linux, this workaround is applied to the compat string cdns,i2c-r1p10 and not for cdns,i2c-r1p14. We could probably use the same approach rather than needing an explicit config setting. See what I did in drivers/i2c/i2c_xilinx_axi.c where the dyn_read_working flag is set based on the version in the compat string.

@mausys
Copy link
Contributor Author

mausys commented Oct 24, 2025

But as @teburd noted, this would add minor driver overhead for newer IP versions.

@teburd
Copy link
Contributor

teburd commented Oct 24, 2025

But as @teburd noted, this would add minor driver overhead for newer IP versions.

The compat string should be ifdef usable? If not this is something we should fix long term, and you should continue with the Kconfig option.

@cfriedt cfriedt merged commit 31d16f3 into zephyrproject-rtos:main Oct 24, 2025
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment