I3C in Tomorrow's Designs: Miqu' El Raynal

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 52

Embedded Linux Conference, Fall 2021

I3C in tomorrow’s
designs  

Miquèl Raynal
miquel@bootlin.com

© Copyright 2004-2021, Bootlin.


Creative Commons BY-SA 3.0 license.
embedded Linux and kernel engineering
Corrections, suggestions, contributions and translations are welcome!

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 1/1
Miquèl Raynal
 

I Embedded Linux engineer at Bootlin


I Embedded Linux expertise
I Development, consulting and training
I Strong open-source focus
I https://bootlin.com
I Contributions
I Maintainer of the NAND subsystem
I Co-maintainer of the MTD subsystem
I Kernel support for various ARM SoCs
I Contributor to the I3C sybsystem
I Living in Toulouse, south west of France

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 2/1
Embedded Linux Conference, Fall 2021
 

Yet another serial


bus?  

Miquèl Raynal
miquel@bootlin.com

© Copyright 2004-2021, Bootlin.


Creative Commons BY-SA 3.0 license.
embedded Linux and kernel engineering
Corrections, suggestions, contributions and translations are welcome!

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 3/1
Electrical engineering 101
 

You are a hardware designer.

You want to wire a simple device to a custom board.

What bus do you pick?

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 4/1
Electrical engineering 101
 

I Existing device interfaces?


I Power consumption targets?
I Expected throughput?
I Wiring constraints?
I Number of devices?

I Pick one:
I OneWire? Too simple/slow?
I RS232? Really?
I USB? Really suitable for embedded systems?
I I2C? Why not?
I SPI? Yeah, still trendy?

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 5/1
Electrical engineering 101
 

You are a hardware designer.

Now you want to wire several devices.


You have minimal bandwidth constraints.
The devices are a bit complex.

What bus do you pick?

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 6/1
State of the art
 

I I2C is pretty slow (400kHz); SPI is fast (up to 100MHz)


I Slowest exchanges will last longer
I Longer exchanges will increase the power consumed per bit
transmitted ratio
I Slow bus with many devices means extra delays
I SPI needs one physical CS per device; I2C doesn’t, but suffers
from address collision issues (lack of virtual addressing)
I Extra wires on a serial bus are costly
I I2C won’t natively support more than a couple of identical
devices
I In both cases, if asynchronous signaling is needed (IRQ), an
additional line must be wired
I Devices not available anymore on the bus after entering low
power modes
I Devices don’t natively belong to a particular “class” sharing a
set of properties (easing the tuning of a set of devices)
- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 7/1
Here comes I3C
 

I Improved Inter Integrated Circuit


I MIPI Alliance specification
I Targets automotive, consumer electronics, IoT market
I Two-wire bus with the following main features:
I Reasonably high throughput
I Colorful set of commands
I Dynamic address assignment
I Self-describing devices (USB-like)
I In-band signaling
I Hot-join
I Controller handover
I Advanced low-power modes
I And more...
I Partially backward compatible with I2C

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 8/1
Backward compatibility with I2C
 

I Main goal:
I Ease acceptance
I Improve the re-usability of existing devices
I Designed with I2C in mind
I At physical level:
I Compatible Voltage levels
I A clock and a data line
I Adaptable clock frequencies
I Support for open-drain output
I At logical level:
I 7-bits addressing
I Comparable S/Sr/P/ACK/NACK behavior
I Use tricks to talk to I2C and I3C devices on the same bus

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 9/1
Embedded Linux Conference, Fall 2021
 

The I3C protocol  

Miquèl Raynal
miquel@bootlin.com

© Copyright 2004-2021, Bootlin.


Creative Commons BY-SA 3.0 license.
embedded Linux and kernel engineering
Corrections, suggestions, contributions and translations are welcome!

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 10/1
Achieving higher frequencies
 

I I2C relies on open-drain outputs with pull-ups


I I3C relies on push-pull mode
I SCL always in push-pull mode
I SDA alternating push-pull and open-drain

⇒ faster rising times


- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 11/1
Pure I3C frequencies
 

I3C bus typical frequency is 12.5MHz. A “Pure Bus” supports:


I SDR (Simple Data Rate) mode achieves 12.5Mpbs
I SDR is the default mode and should be supported by all I3C
devices
I Optional HDR (High Data Rate) modes
I Double Data Rate (HDR-DDR) achieves 25Mbps
I Still uses the clock
I Samples data on both edges of the clock
I Ternary Symbol Pure (HDR-TSP) achieves 33.3Mbps
I Both signals are considered data
I Tracks edges rather than levels
I Each transition is a clock cycle, the bus is capable of
expressing three states: SCL transitioned, SDA transitioned,
SCL and SDA transitioned
The MIPI alliance states that higher frequencies only work well with
point-to-point topologies:
https://www.mipi.org/resources/I3C-frequently-asked-questions

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 12/1
Pure I3C frequencies
 

I The controller must advertise all targets that it is entering a


HDR mode and which mode it has chosen
I If a device does not support the chosen HDR mode that the
controller is entering, it can simply wait for the HDR mode to
be exited
I All targets should support tracking the HDR exit pattern
I 4 SDA fall transitions with SCL low before a P pattern
I The HDR exit pattern detector is very cheap to implement
(simply with 4 latches in series)

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 13/1
Bandwidth: mixed modes
 

I SCL being configured in push-pull, clock stretching is not


allowed
I I2C devices must not be confused by the high-frequency
exchanges
I Most I2C devices already have a 50ns anti-glitch spike filter
I I3C max bus frequency: 12.5MHz ⇒ 80ns clock period
I When talking at 12.5MHz I2C devices won’t even notice clock
changes
I Asymmetrical clock: less than 50% duty cycle in order to keep
the low state longer than 50ns and be sure to be filtered out
before reaching the I2C device
I A “Mixed Fast Bus” supports the following clock modes:
I SDR
I HDR-DDR
I Ternary Symbol Legacy (HDR-TSL) in place of HDR-TSP
I If an I2C device has no spike filter, it’s considered a “Mixed
Slow/Limited bus”, the bus may only work at the slowest
device speed
- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 14/1
Enhanced bus management
 

I Common Command Codes (CCC)


I Standardization of the bus management
I Serve all kind of purpose
I Supports broadcast and direct addressing
I CCCs are always sent to the broadcast address
I 0x7E is the I3C broadcast address
I 0x7E is reserved in the I2C specification
I All I3C devices should listen at the entire command

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 15/1
Common Command Codes (CCC)
 

I ENTDAA: Start a DAA procedure (auto-discovery procedure)


I ENTASX: Enter Activity State (related to power management)
I GETPID: Get Provisional ID (related to device identification)
I GETBCR: Get Bus Characteristics Register (related to device
capabilities)
I GETDCR: Get Device Characteristics Register (related to device
classification)
ENEC, DISEC, ENTAS0, ENTAS1, ENTAS2, ENTAS3, RSTDAA,
ENTDAA, DEFSLVS, SETMWL, SETMRL, ENTTM, ENTHDR0, ENTHDR1,
ENTHDR2, ENTHDR3, ENTHDR7, SETXTIME, ENEC, DISEC, ENTAS0,
ENTAS1, ENTAS2, ENTAS3, RSTDAA, SETDASA, SETNEWDA, SETMWL,
SETMRL, GETMWL, GETMRL, GETPID, GETBCR, GETDCR, GETSTATUS,
GETACCMST, SETBRGTGT, GETMXDS, GETHDRCAP, SETXTIME,
GETXTIME...

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 16/1
Dynamic Address Assignment (DAA)
 

I Regular exchanges on the I3C bus require a dynamic 7-bit


address
I I2C devices already have one and the controller knows about
them
I Must be statically described, like any regular I2C device
I I3C devices must get part of the DAA procedure in order to
receive a 7-bit dynamic identifier
I Unless they have a static address as well and the controller
knows about it
I Or they are in a deep sleep state/powered down at that
moment
I They will require the DAA procedure to be resumed when they
will become available

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 17/1
Device unique identification
 

I Each device has its own unique Provisional ID (PID) 48-bit


identifier:
I 15 bits for the MIPI manufacturer ID
I 1 bit indicating if the below values are random or not
I 32 bits for the Part ID, Instance ID and more bits left to the
vendor to define
I Device also advertise a Bus Characteristics Register BCR which
contains:
I The device role (controller/target)
I Its potential SDR limitations
I Its HDR capabilities
I Its offline capabilities
I Its in-band signaling capabilities
I It also has a Device Characteristics Register DCR which
describes the type of device (accelerometer, thermometer,
composite, etc)
I This calls for standardized interfaces!
I PID, BCR and DCR will be advertised during the DAA procedure
- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 18/1
 

DAA

The controller sends ENTDAA, generates a Sr and sends the


broadcast address (0x7E).

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 19/1
 

DAA

All I3C devices are expected to ACK.

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 20/1
 

DAA

All I3C devices send their PID.

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 21/1
 

DAA

The target with the highest PID looses the arbitration (thanks to
the open-drain nature of the SDA line during this exchange).

The winning device sends its PID followed by its BCR and DCR.
- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 22/1
 

DAA

The controller sends a 7-bit address to the winning device that will
become its own dynamic address.

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 23/1
 

DAA

The target will acknowledge this dynamic address.

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 24/1
 

DAA

The controller generates a (Sr) condition and sends the broadcast


address again.

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 25/1
 

DAA

All devices that have not yet received a dynamic address should
ACK it again.

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 26/1
 

DAA

The new winning device sends its identification numbers.

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 27/1
 

DAA

The controller provides to the device a different dynamic address.

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 28/1
 

DAA

The target device again acknowledges its new dynamic address.

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 29/1
 

DAA

The controller keeps repeating the procedure...

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 30/1
 

DAA

...until there are no more devices acknowledging the request


anymore, this means all woken-up devices have their dynamic
address and the bus is now operational.

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 31/1
 

IBIs
I Device driven In-Band Interrupts
I The device can raise an interrupt in the following conditions:
I The controller initiate a start condition: SDA low then SCL low
I The bus is idle, the device asserts SDA low and waits for the
controller to acknowledge the interrupt by pulling SCL low to
end the start condition
I Device sends its address with a RnW bit to 1
I Priority arbitration depends on the dynamic address
I Address exchange in open drain mode
I 0 has a higher “priority” than 1
I Lowest address ⇒ highest priority
I Controller ACKs or NACKs the interrupt
I Some devices may also provide a mandatory byte that the
controller must read
I The controller decides to emit a Sr and continue talking on
the bus or emits a P
- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 32/1
Hot-join
 

I Devices can be unpowered and powered back at any moment,


thus improving the energy savings
I Physically plugged-in devices at run-time
I A hot-join request is very much like an IBI but the device will
provide a reserved address followed by a specific RnW bit to 0
in order to request a new DAA round

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 33/1
Controller handover
 

I Controller handover works very similarly than a hot-join, the


device sending its own address this time, and keeping the
RnW bit set to 0
I If the current controller does not feel ready, it may NACK the
request
I The offended target may request to be granted primary
controller later
I If the controller agrees, it needs to prepare the bus for
hand-off
I Disable specific requests, wait for targets to finish their current
processing, disable interrupts, ...
I Assert a particular CCC to proceed the hand-off and end the
transaction with a P
I Arbitration has been lost, the controller should release the lines
and check that the new controller now asserts its controllership

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 34/1
Time synchronization (I3C v1.1)
 

I A device might receive the order from the controller to


generate samples at a given rate instead of on-demand only
I Controller would issue a SETXTIME to setup the frequency
I The target is then suppose to generate an IBI each time it
triggers a sample

I Also a way of synchronizing different devices if an external low


power clock is shared among several devices in order to trigger
the sampling

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 35/1
Reset (I3C v1.1)
 

I Global reset:
I Upon error showing that the bus is currently stuck, the I3C
controller is capable of sending a global reset over the bus
I Only supposed to reset the bus controller of each device
I Implies restarting the DAA procedure

I Targeted reset:
I A target might request to be reset
I Saves an extra line on the final design
I Involves asking all the devices but the one requesting the reset
to discard the comming “reset pattern”

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 36/1
Reset (I3C v1.1)
 

I RSTACT specifies how the targets should react to a “reset


pattern”:
I Discard
I Reset the bus controller
I Reset the entire chip
I A reset pattern is made of 14 SDA transitions with SCL kept
low, a Sr and finally a P

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 37/1
Bulk Transport (I3C v1.1)
 

I New Bulk Transport (HDR-BT) mode for Bulk messages


I Typical use: direct mapping of a SRAM
I Enhanced CRC checks with the sender knowing rapidly if the
transfer must be repeated
I Lowered overhead
I The target can drive SCL during reads to avoid
round-trip-time issues during long transfers

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 38/1
Multi-Lane (I3C v1.1)
 

I After so much efforts to keep everything in-band as much as


possible, it was time to add new wires...
I SDR-ML DUAL
I SDR-ML QUAD
I HDR-DDR-ML DUAL
I HDR-DDR-ML QUAD
I HDR-TSP-ML DUAL
I HDR-TSP-ML QUAD
I HDR-BT-ML DUAL
I HDR-BT-ML QUAD

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 39/1
Embedded Linux Conference, Fall 2021
 

Linux API  

Miquèl Raynal
miquel@bootlin.com

© Copyright 2004-2021, Bootlin.


Creative Commons BY-SA 3.0 license.
embedded Linux and kernel engineering
Corrections, suggestions, contributions and translations are welcome!

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 40/1
The I3C framework
 

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 41/1
Design choices
 

I Built as a separate subsystem than I2C in order not to break


the I2C framework
I The subsystem defines:
I A struct i3c_bus bus object
I A struct i3c_master_controller controller structure
I A rather exhaustive struct i3c_master_controller_ops
interface
I All the necessary APIs to register:
I A controller
I A device driver
I IBIs
I Device-driver binding are based on the device’s PID

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 42/1
The I3C bus infrastructure
 

include/linux/i3c/master.h
struct i3c_bus {
struct i3c_dev_desc *cur_master;
int id;
unsigned long addrslots[((I2C_MAX_ADDR+1) * 2) / BITS_PER_LONG];
enum i3c_bus_mode mode;
struct {
unsigned long i3c;
unsigned long i2c;
} scl_rate;
struct {
struct list_head i3c;
struct list_head i2c;
} devs;
struct rw_semaphore lock;
};

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 43/1
The I3C controller structure
 

include/linux/i3c/master.h
struct i3c_master_controller {
struct device dev;
struct i3c_dev_desc *this;
struct i2c_adapter i2c;
const struct i3c_master_controller_ops *ops;
unsigned int secondary : 1;
unsigned int init_done : 1;
struct {
struct list_head i3c;
struct list_head i2c;
} boardinfo;
struct i3c_bus bus;
struct workqueue_struct *wq;
};

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 44/1
The I3C controller interface
 

include/linux/i3c/master.h
struct i3c_master_controller_ops {
/* Bus management */
int (*bus_init)(struct i3c_master_controller *master);
void (*bus_cleanup)(struct i3c_master_controller *master);
int (*do_daa)(struct i3c_master_controller *master);
/* I3C devices management */
int (*attach_i3c_dev)(struct i3c_dev_desc *dev);
int (*reattach_i3c_dev)(struct i3c_dev_desc *dev, u8 old_dyn_addr);
void (*detach_i3c_dev)(struct i3c_dev_desc *dev);
/* CCCs transactions */
bool (*supports_ccc_cmd)(struct i3c_master_controller *master,
const struct i3c_ccc_cmd *cmd);
int (*send_ccc_cmd)(struct i3c_master_controller *master, struct i3c_ccc_cmd *cmd);
/* Private SDR transfers */
int (*priv_xfers)(struct i3c_dev_desc *dev, struct i3c_priv_xfer *xfers, int nxfers);
/* I2C devices management */
int (*attach_i2c_dev)(struct i2c_dev_desc *dev);
void (*detach_i2c_dev)(struct i2c_dev_desc *dev);
int (*i2c_xfers)(struct i2c_dev_desc *dev, const struct i2c_msg *xfers, int nxfers);
/* IBI management */
int (*request_ibi)(struct i3c_dev_desc *dev, const struct i3c_ibi_setup *req);
void (*free_ibi)(struct i3c_dev_desc *dev);
int (*enable_ibi)(struct i3c_dev_desc *dev);
int (*disable_ibi)(struct i3c_dev_desc *dev);
void (*recycle_ibi_slot)(struct i3c_dev_desc *dev, struct i3c_ibi_slot *slot);
};

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 45/1
Additional information about bus initialization
 

I The core parses the information provided by the DT


I Static devices are instantiated on this base
I Calls the ->bus_init() callback to initialize the controller
I Calls the ->do_daa() callback to start the device discovery
I Assigns dynamic addresses DAA
I The way the controller wants to follow the DAA procedure is
really open
I For each device discovered, the controller driver calls
i3c_master_add_i3c_dev_locked() to notify the core
I The core then registers the discovered devices to the device
model

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 46/1
The device interface
 

include/linux/i3c/device.h
struct i3c_device {
// Generic 'device-model' device structure
struct device dev;
// Internal representation of an I3C device
struct i3c_dev_desc *desc;
// Representation of the I3C bus, not tight to a specific
// controller due to controller handover possibilities
struct i3c_bus *bus;
};

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 47/1
An I3C device driver
 

Dummy I3C device driver


static int dummy_i3c_probe(struct i3c_device *i3cdev)
{
...
i3cdev_set_drvdata(i3cdev, data);
}

static int dummy_i3c_remove(struct i3c_device *i3cdev)


{
void *data = i3cdev_get_drvdata(i3cdev);
...
}

static const struct i3c_device_id dummy_i3cdev_ids[] = {


I3C_DEVICE(<manufid>, <partid>, <driver-data>),
{ /* sentinel */ },
};

static struct i3c_driver dummy_i3c_drv = {


.driver = {
.name = "dummy-i3c",
},
.id_table = dummy_i3cdev_ids,
.probe = dummy_i3c_probe,
.remove = dummy_i3c_remove,
};
module_i3c_driver(dummy_i3c_drv);

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 48/1
Interacting with the I3C device
 

SDR transfers
u8 reg = 0x5, values[2];
struct i3c_priv_xfer xfers[2] = {
{
.flags = 0,
.len = 1,
.data.out = &reg,
},
{
.flags = I3C_PRIV_XFER_READ,
.len = 2,
.data.in = values,
},
};

ret = i3c_device_do_priv_xfers(i3cdev, xfers, ARRAY_SIZE(xfers));


if (ret)
return ret;

⇒ CCCs for now are not exposed (subject to evolution)

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 49/1
Using IBIs
 

/* Called in a non-atomic context (workqueue) */


static void ibi_handler(struct i3c_device *i3cdev,
const struct i3c_ibi_payload *payload);

static int probe(struct i3c_device *i3cdev)


{
struct i3c_ibi_setup ibireq = {
.handler = ibi_handler,
.max_payload_len = 2,
.num_slots = 10,
};

...
ret = i3c_device_request_ibi(dev, &ibireq);
if (ret)
return ret;

ret = i3c_device_enable_ibi(dev);
if (ret)
return ret;
...
}

static int remove(struct i3c_device *i3cdev)


{
i3c_device_disable_ibi(i3cdev);
i3c_device_free_ibi(i3cdev);
...
}

⇒ Slots are pre-allocated, possible overlap if not unqueued fast enough


- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 50/1
Status and to-do list
 

I Things have moved forward


I Hardware manufacturers more and more interested
I Three controller drivers upstream
I One IMU device driver upstream (not fully leveraging the
power of I3C yet)
I Ongoing controller handover work
https://lkml.kernel.org/lkml/1606716983-3645-1-
git-send-email-pthombar@cadence.com/

I There is still room for improvement


I HDR support
I I3C target interface
I Global and directed resets
I Time synchronization
I /dev interface with additional user controls?
I ...

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 51/1
Thanks!
 

Questions? Suggestions?
Comments?
Miquèl Raynal
miquel@bootlin.com

Slides under CC-BY-SA 3.0


https://bootlin.com/pub/conferences/2021/i3c/raynal-i3c

- Kernel, drivers and embedded Linux - Development, consulting, training and support - https://bootlin.com 52/1

You might also like