Earlier this week I attended Linux Plumbers Conference 2019. Among the sessions I attended, the most relevant to me has been the BoF session led by I2C Linux maintainer Wolfram Sang: “New hardware with modern I2C address conflicts“.
The goal was to discuss changes needed to the Linux kernel I2C subsystem to support video serializer and deserializer chipsets (“serdes”). These chips allow to access the I2C bus on multiple remote camera or display modules from a single I2C master controller on the main SoC.
Following is a brief report of the discussion.
Wolfram started presenting his camera module use case. He works for Renesas, uses Maxim GMSL chips on an automotive development board with 8 cameras connected on two 4-camera deserializers sharing a unique I2C master from the main SoC.
All serializers and sensors have the same address when powered up, however each of those chips supports reprogramming its slave address. The serdes chipset act as an I2C mux, unfortunately they have all the 4 channels ON by default. This requires a complex reconfiguration phase to avoid address conflicts: each time the cameras are started, all mux ports are closed, then one by one opened and the addresses reprogrammed.
Vitor Soares entered the discussion saying that the I3C bus, unlike I2C, has dynamic address assignment: by default the master assigns a unique slave address dynamically at connection time. I3C also has group addresses. However I3C adoption in current chips seems still very low (“I3C is coming to the real world?”, said Wolfram ironically).
Linus Walleij asked if, even though ugly, a solution could be to reconfigure all the addresses in the bootloader before starting the kernel. It turns out it is not possible because the remote camera modules can be powered on/off at runtime and they lose the address each time.
Luca’s use case
Then Luca presented his use case. The structure is similar, but here the camera modules can be disconnected and reconnected at runtime, potentially with a different model of camera module and while recording from the other camera. This looks like hot-plug.
He uses Texas Instruments FPD-Link III chips, which remap the physical address to an alias instead of being equivalent to an I2C mux. This avoids entirely the need for address reprogramming on the slave chips to avoid address collisions.
Luca previously sent his RFCv2 patches, whose notable design choices include:
- an I2C adapter is instantiated for each remote I2C bus
- when a device is added on a remote bus, an alias is chosen for it from a pool
- the pool of usable aliases is defined in device tree, and must contain addresses known to be unused by physical chips
Tablet use case
Chen-Yu Tsai presented his use case for a tablet product. Key points in this design:
- There is no serdes involved
- The SoC is connected to 2 identical cameras, same i2c bus, same address
- Both cameras are connected on the same MIPI CSI-2 port
- There is 1 power line per camera, but the reset line is shared
This use case is quite different from the ones discussed. But the select/deselect callbacks could be useful here, said Wolfram.
Laurent Pinchart said having 2 cameras on same MIPI CSI-2 line is a common hardware design.
An important topic is how to select an address to assign to each newly connected remote slave (no matter if it will be changed on the slave itself or it will be remapped to an alias). Wolfram thinks this should be done dynamically.
Wolfram had proposed that all slave addresses not described as used are considered available. He’s not 100% happy with this idea, but he thinks it’s better than listing in device tree a pool of available addresses, as initially proposed by Luca in his patches. After all, device tree should describe what hardware exists, not what does not exist. But this means we’ll need a device tree binding for addresses that are used by a physical device, but whose driver is unknown or not implemented.
Alexandre Belloni asked if this can work also when a chip is defined, because it physically exists, but is disabled in device tree. He has a use case for this, a board with a chip that is installed but whose driver is known to be buggy. Wolfram replied we should fix that in device tree management and still consider the address as used.
Overall, even though the idea of “all-non-described-addresses-are-available” leaves nobody super happy, there was no real objection to it.
Wolfram said he likes the idea of instantiating an I2C adapter per each remote bus, and he doesn’t understand the downside of not doing it. It makes things clearer, he said.
Jacopo Mondi added that this approach also allows to have different bus speeds on each segment, as the TI chips allow to do.
Wolfram commented on his previous proposal of adding a flag (
NEEDS_ATR) to the I2C adapters for remote busses. If this flag is set, when adding a new device the framework would choose an available address, then call a callback on the adapter (the deserializer driver) to apply the binding in the chip.
This would work for the TI chips that use aliases, but for the Maxim chips (looking like a mux) we have to pass the new address to the slave chip driver. Wolfram suggests to augment the
i2c_client struct that is passed to the chip probe() function with a field containing the address to be reprogrammed.
Luca observed that in this case the core doesn’t know whether the new
i2c_client field has been honored, i.e. whether address reprogramming it is doable by the chip and implemented in the driver. So we probably need a
CAN_REPROGRAM_ADDRESS flag in the slave drivers to let the I2C core know.
Niklas Söderlund said this could be achieved with a multi-level approach: when the NEEDS_ATR flag is set the core chooses an address and calls an adapter callback; if the callback doesn’t exist (or returns error) then calls the device callback to set an address.
Jacopo pointed out that the client should be aware at probe time, not later in a callback, or it will be known too late.
A primary goal of the BoF was to let people share their use cases involving I2C address remapping. Since no new relevant use cases emerged, the discussion mostly focused on the possible implementations that had already been discussed on the linux-i2c mailing list. The discussion focused on the details, thus it looks like there is a good consensus on the core of the idea. One less obstacle to proceed to the implementation, apparently.