\documentclass[aspectratio=169,obeyspaces,spaces,hyphens,dvipsnames]{beamer}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}% http://ctan.org/pkg/lm
\usepackage{minted}
\usepackage{hyperref}
\usepackage{xcolor}
\usepackage{pgfplots}
\usepackage{tikz}
\usepackage[normalem]{ulem}
\usepackage{textcomp}

\mode<presentation>
\usetheme{Bootlin}

\def\signed #1{{\leavevmode\unskip\nobreak\hfil\penalty50\hskip2em
  \hbox{}\nobreak\hfil(#1)
  \parfillskip=0pt \finalhyphendemerits=0 \endgraf}}

\newsavebox\mybox
\newenvironment{aquote}[1]
  {\savebox\mybox{#1}\begin{quotation}}
  {\signed{\usebox\mybox}\end{quotation}}

\title{I + I²C = I3C}
\conference{ELC 2018}
\authors{Boris Brezillon}
\email{boris@bootlin.com}
\institute{Bootlin}
\slidesurl{https://bootlin.com/pub/conferences/2018/elc/i3c/}

\begin{document}

\addtocontents{toc}{\protect\setcounter{tocdepth}{-1}}
\section{I + I²C = I3C, what's hiding in this additional 'I'}
\addtocontents{toc}{\protect\setcounter{tocdepth}{2}}

\begin{frame}{Boris Brezillon}
  \begin{itemize}
  \item Embedded Linux engineer and trainer at Bootlin
    \begin{itemize}
    \item Embedded Linux {\bf development}: kernel and driver
      development, system integration, boot time and power
      consumption optimization, consulting, etc.
    \item Embedded Linux, Linux driver development, Yocto Project / OpenEmbedded
      and Buildroot {\bf training courses}, with materials freely
      available under a Creative Commons license.
    \item \url{https://bootlin.com}
    \end{itemize}
  \item Contributions
    \begin{itemize}
    \item {\bf Maintainer of the MTD subsystem}
    \item {\bf Kernel support for various ARM SoCs}
    \item {\bf Submitted RFCs for an I3C subsystem}
    \end{itemize}
  \item Living in {\bf Toulouse}, south west of France
  \end{itemize}
\end{frame}

\begin{frame}{'I' like in ...}
  \begin{itemize}
  \item I²C == Inter Integrated Circuit
  \item I3C == {\bf Improved} Inter Integrated Circuit
  \item If it's improved, it's obviously better
  \end{itemize}
\end{frame}

\begin{frame}
  \begin{center}
  \Huge
  Questions? Suggestions? Comments?\\
  \vspace{1.5cm}
  \huge
  Boris Brezillon\\
  \large
  \vspace{0.5cm}
  \hspace{2.6cm}\code{boris@bootlin.com}
  \vspace{0.5cm}
  \newline Slides under CC-BY-SA 3.0\\
  \scriptsize
  \url{https://bootlin.com/pub/conferences/2018/elc/bbrezillon-i3c/}
  \end{center}
\end{frame}

\begin{frame}
  \begin{center}
  \Huge
  Backup slides\\
  \large
  (for those who need more to be convinced)\\
  \end{center}
\end{frame}

\subsection{Introduction}

\begin{frame}{I²C and SPI: fine but could do better}
  \begin{itemize}
  \item I²C and SPI have long been the primary choice for embedded
	devices
    \begin{itemize}
    \item[+] Both are relatively simple to implement (slaves and masters)
    \item[+] Both require a limited amount of pins
    \item[--] I²C is quite slow
    \item[--] SPI requires one extra \code{CS} pin per device
    \item[--] Both need an extra pin per device to signal interrupts
    \item[--] Both don't support hotplug
    \item[--] Both don't support automated device discovery (though I²C
      bus can be scanned to know if a device is present at a specific
      address)
    \item[--] Address collisions on I²C buses
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{I3C: an attempt at addressing I²C/SPI limitations}
  \begin{itemize}
  \item What if we could improve SPI and I²C to make something even
	more attractive
  \item Here comes I3C (MIPI standard):
    \begin{itemize}
    \item[+] Only 2 pins required
    \item[+] In Band Interrupts
    \item[+] Higher throughput (up to 35Mb/s)
    \item[+] Better energy efficiency than I²C on a per-transmitted-bit basis
    \item[+] Supports hotplug
    \item[+] Devices are discoverable
    \item[+] Dynamic address assignment to avoid address collisions
    \item[+] Backward compatible with I²C (to some extent)
    \item[+] [Standardization of device profiles?]
    \item[--] Likely harder to implement
    \end{itemize}
  \end{itemize}
\end{frame}

\subsection{Few details about the protocol}

\begin{frame}{I3C: backward compatibility with I²C}
  \begin{itemize}
  \item I3C has been designed with I²C backward compatibility in mind
  \item Why?
  \item Because of the existing I²C slaves ecosystem (a huge variety of
    sensors and other kind of devices are controlled over I²C)
  \item Transition to systems containing only I3C sensors/slaves is
    likely to take long
  \item Some new/fancy sensors/slaves will support I3C natively
  \item But you'll still have to embed I²C slaves to have a full-blown
    system until I3C equivalences are available
  \item Backward compatibility is a two-way problem:
    \begin{itemize}
    \item You'll have to connect I²C slaves on an I3C bus
    \item Slave vendors might want to make their new I3C-compatible
      devices backward compatible with I²C so that can can
      indifferently be connected on an I3C or I²C bus
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{I3C vs I²C: physical layer}
  \begin{itemize}
  \item Similarities:
    \begin{itemize}
    \item Only 2 signals: SDA (data) and SCL (clock)
    \item SDA in open-drain with a pull-up
    \item Start/RepeatedStart/Stop/Ack/Nack conditions are unchanged
    \end{itemize}
  \item What has changed:
    \begin{itemize}
    \item SCL in push-pull \textrightarrow{}
      \begin{itemize}
      \item Devices doing clock-stretching are not allowed
      \item Clock frequency can be higher (due to faster rising edge)
      \end{itemize}
    \item SDA switches to push-pull when possible (to improve
      throughput and reduce power consumption)
    \item HDR (High Data Rate) modes (DDR or Ternary based modes)
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{I3C vs I²C: why switching to push-pull?}
  \begin{center}
  \includegraphics[height=0.5\textwidth]{open-drain-vs-push-pull.pdf}
  \end{center}
\end{frame}

\begin{frame}{I3C vs I²C: but I²C is open-drain...}
  \begin{itemize}
  \item Why?
    \begin{itemize}
    \item It's simpler to implement
    \item Allows any device to easily take control of the bus:
      \begin{itemize}
      \item Default state is high-level
      \item The line is driven low if one or more devices set it low
      \item No risk of having 2 devices driving the line at two different
        levels
      \end{itemize}
    \end{itemize}
  \item Remember that I3C wants to be backward compatible with I²C
    \begin{itemize}
    \item SCL can easily be switched to push-pull if only one device
      (the master) drives it \textrightarrow{}
      \begin{itemize}
      \item No clock-stretching
      \item No I²C-like multi-master
      \end{itemize}
    \item SDA still needs to be controlled by slaves at specific time
      (to ACK/NACK a transaction)
    \item I3C Master should dynamically switch from open-drain to
      push-pull during a transaction
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{I3C: what about performance?}
  \begin{itemize}
  \item SCL can run at up to 12.5 MHz in push-pull mode
    \textrightarrow{} ~1.4 MByte/s
  \item Problem: I²C devices don't support such high-speed SCL
    \begin{itemize}
    \item We need to slow down SCL when I²C devices are present on the
      bus...
    \item ... unless we find a way to let them think the SCL signal
      stays low and exclude them from pure I3C transactions
    \item Luckily, some devices have spike filters, filtering any
      changes that are maintained less than 50 ns
    \end{itemize}
  \item I3C takes benefit of that by using an asymmetric SCL signal:
    \begin{itemize}
    \item SCL stays high less than 50 ns (usually 40 ns since 12.5 MHz
      implies a 80 ns period)
    \item The low period is extended (more than 50 ns) so that the I²C
      device always sees a logical low-level
    \end{itemize}
  \item With this trick performance is still lower than when you
      have only I3C devices on the bus
  \end{itemize}
\end{frame}

\begin{frame}{I²C: 50 ns spike filter}
  \begin{center}
  \includegraphics[height=0.5\textwidth]{50ns-filter.pdf}
  \end{center}
\end{frame}

\begin{frame}{I3C: bus configurations}
  \begin{itemize}
  \item Pure Bus: only I3C devices connected on the bus
    \begin{itemize}
    \item SCL can be set to 12.5MHz
    \item All HDR modes can be used
    \item This is the ideal case in term of performance
    \end{itemize}
  \item Mixed Fast Bus: I3C and I²C devices connected on the bus, but
    I²C devices have a 50 ns spike filter
    \begin{itemize}
    \item SCL has to be lower (usually around 8.3MHz if you make low
      period twice as big as high period)
    \item HDR-DDR and HDR-TSL can be used
    \item This is a good compromise when you have to connect both I²C
      and I3C device on an I3C bus
    \end{itemize}
  \item Mixed Slow Bus: I3C and I²C devices connected on the bus, but
    some I²C devices do not have a 50 ns spike filter
    \begin{itemize}
    \item SCL is limited to the slowest I²C device on the bus
    \item HDR modes are not supported
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{I3C vs I²C: addressing scheme}
  \begin{itemize}
  \item Similarities:
    \begin{itemize}
    \item 7-bit addresses
    \item Devices are expected to ACK/NACK transactions
    \end{itemize}
  \item What has changed:
    \begin{itemize}
    \item Broadcast address (\code{0x7e})
      \begin{itemize}
      \item Can be used to address all I3C devices
      \item Has been picked from the reserved address space of I²C to
        avoid collision with I²C devices
      \end{itemize}
    \item Addresses are no longer statically assigned: dynamically
      assigned by the master
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{I3C: I²C backward compatibility, let's sum-up}
  \begin{itemize}
  \item Similarities in the PHY and MAC layer are motivated by backward
    compatibility
  \item Still, not all I²C slaves can be connected on an I3C bus along
    with I3C devices
    \begin{itemize}
    \item Slaves doing clock-stretching are forbidden
    \item Having a 50 ns spike filter on the I²C slaves end is
      recommended if you want to achieve acceptable performance on I3C
      transactions
    \item Don't forget that some HDR modes can't be used when I²C
      devices are present on the bus
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{I3C vs I²C: functional differences}
  \begin{itemize}
  \item This is probably the most interesting part for software
    developers
  \item I3C is functionally far from I²C:
    \begin{itemize}
    \item Devices are assigned addresses by the master dynamically
    \item Devices can be automatically discovered
    \item Devices are self-descriptive (similar to USB devices)
    \begin{itemize}
      \item Manufacturer and part id exposed
      \item Concept of device class
      \item Devices expose their bus-related capabilities
    \end{itemize}
    \item Some masters/slaves are hotplug-friendly
    \item Bus management is more advanced/controlled than with I²C
    \item Provides different types of transactions
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{I3C: \code{CCC} transactions or how to manage the bus}
  \begin{itemize}
  \item I²C specification defines the bare minimum:
    \begin{itemize}
    \item How to transmit things on the bus
    \item How to interact with devices (address them and exchange data)
    \item Lacks generic protocol to do bus management operations
  \end{itemize}
  \item I3C protocol is more complex and I3C masters have a few more
    responsibilities:
    \begin{itemize}
    \item Discover devices connected on the bus
    \item Query information about those devices
    \item Keep the bus in a consistent state
    \item Do generic operations
    \end{itemize}
  \item Requires standardization of bus management related operations
  \item This is done with \code{CCC} (Common Command Codes)
    transactions
  \end{itemize}
\end{frame}

\begin{frame}{I3C: \code{CCC} frame format}
  \begin{itemize}
  \item An 8-bit opcode
    \begin{itemize}
    \item Bit 7: 0 \textrightarrow{} broadcast, 1 \textrightarrow{} unicast
    \item In case of unicast commands, the destination address is stored
      in the payload
    \end{itemize}
  \item 0 to N bytes of payload
    \begin{itemize}
    \item Opcode id defines whether the payload should be read or written
    \item Payload length depends on the opcode
    \end{itemize}
  \item A few examples:
    \begin{itemize}
    \item \code{ENTDAA}: Start a DAA procedure (auto-discovery
      procedure)
    \item \code{ENTASX}: Enter Activity State (related to power management)
    \item \code{GETPID}: Get Provisional ID (related to device
      identification)
    \item \code{GETBCR}: Get Bus Characteristics Register (related to
      device capabilities)
    \item \code{GETBCR}: Get Device Characteristics Register (related to
      device classification)
    \item ...
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{I3C: Discovering devices connected on the bus}
  \begin{itemize}
  \item Discovery is done with the \code{ENTDAA} broadcast CCC command
  \item Every I3C slave device connected to the bus should reply to
    this command
  \item The Master follows the \code{ENTDAA} command by a RepeatedStart and
    waits for an ACK (which can be asserted by several devices since
    SDA is open drain in this situation)
  \item Every device connected on the bus should start emitting the
    following data:
    \begin{itemize}
    \item \code{PID}: Unique ID containing a manufacturer ID, a part
          ID and an instance ID
    \item \code{BCR}: The Bus Characteristics Register
    \item \code{DCR}: The Device Characteristics Register
    \end{itemize}
  \item While emitting, the slave should monitor the SDA state, and
    stop emitting as soon as SDA does not match (arbitration lost)
  \item Master will assign a dynamic address to the winning device
  \item The master will re-emit RepeatedStart until no-one ACKs the
    request, which means all devices have been discovered
  \end{itemize}
\end{frame}

\begin{frame}{I3C: DAA (Dynamic Address Assignment)}
  \begin{center}
  \only<1> {\includegraphics[width=0.9\textwidth]{i3c-daa-start.pdf}}
  \only<2> {\includegraphics[width=0.9\textwidth]{i3c-daa-step1.pdf}}
  \only<3> {\includegraphics[width=0.9\textwidth]{i3c-daa-step2.pdf}}
  \only<4> {\includegraphics[width=0.9\textwidth]{i3c-daa-step3.pdf}}
  \only<5> {\includegraphics[width=0.9\textwidth]{i3c-daa-step4.pdf}}
  \only<6> {\includegraphics[width=0.9\textwidth]{i3c-daa-step5.pdf}}
  \only<7> {\includegraphics[width=0.9\textwidth]{i3c-daa-step6.pdf}}
  \only<8> {\includegraphics[width=0.9\textwidth]{i3c-daa-step7.pdf}}
  \only<9> {\includegraphics[width=0.9\textwidth]{i3c-daa-step8.pdf}}
  \only<10> {\includegraphics[width=0.9\textwidth]{i3c-daa-step9.pdf}}
  \only<11> {\includegraphics[width=0.9\textwidth]{i3c-daa-step10.pdf}}
  \only<12> {\includegraphics[width=0.9\textwidth]{i3c-daa-end.pdf}}
  \end{center}
\end{frame}

\begin{frame}{I3C: Identifying devices connected on the bus}
  \begin{itemize}
  \item PID (Provisional ID): Unique ID formed of several subfields
    \begin{itemize}
    \item Manufacturer ID: 15 bits describing the device manufacturer
    \item Part ID: 16 bits describing the device
    \item Instance ID: 4 bits in case you need to have several
      instances of the same device on a bus. Usually configurable
      through external pins
    \item Extra information: 12 bits. Vendor specific. Still unclear
      what will be placed here
    \end{itemize}
  \item BCR (Bus Characteristics Register): device capabilities
    \begin{itemize}
    \item IBI capable
    \item HDR capable
    \item SDR transfer speed limitations
    \item ...
    \end{itemize}
  \item DCR (Device Characteristics Register): device type. IDs are standardized
    \begin{itemize}
    \item IDs are standardized by MIPI
    \item Will we have common interfaces standardized by MIPI??
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{I3C: SDR private transfers}
  \begin{itemize}
  \item SDR transfers are supposed to replace I²C transfers for I3C
    devices
  \item Uses push-pull mode and higher SCL frequency (up to 12.5MHz)
    when applicable
  \item No standardization of the transfers content: devices are free
    to expose the interface they like
  \end{itemize}
\end{frame}

\begin{frame}{I3C: HDR transfers}
  \begin{itemize}
  \item HDR (High Data Rate) transfers are intended to be used
    by devices that need high throughput
  \item 3 different HDR modes (all optional):
    \begin{itemize}
    \item DDR (Double Data Rate): both edges of the clock are used to
      transmit data
    \item TSP (Ternary Symbol Pure): both SCL and SDA are used to
      encode data. Only applicable to pure I3C buses
    \item TSL (Ternary Symbol Legacy-inclusive-bus): same as TSP except
      it's applicable to buses on which you have I²C devices
    \end{itemize}
  \item Based on 16-bit word transmission
  \item Frame format is defined by the spec \textrightarrow{}
    standard/generic HDR commands are likely to show up
  \end{itemize}
\end{frame}

\begin{frame}{I3C: IBIs or how to make your hardware designer happy}
  \begin{itemize}
  \item IBI stands for In-Band Interrupts
  \item Removes the need for an extra pin to signal interrupts
  \item IBI generation is part of the protocol
    \begin{itemize}
    \item Slave devices can preempt the bus to signal interrupts
    \item Master is still in control and can \code{NACK} \code{IBI}s
    \item \code{IBI}s can be followed by a payload
    \end{itemize}
  \item Address arbitration takes place when several devices send IBIs
    concurrently
  \item The device with the lowest address wins
  \end{itemize}
\end{frame}

\begin{frame}{I3C: Hot-Join}
  \begin{itemize}
  \item New name for hotplug, same feature
  \item I3C devices can signal their presence after the master has
    initialized the bus
  \item The master can \code{ACK} or \code{NACK} the request
  \item In case of \code{ACK}, the master should assign a dynamic
    address to the device by starting a \code{DAA} procedure
  \end{itemize}
\end{frame}

\begin{frame}{I3C: Multi master capabilities}
  \begin{itemize}
  \item I3C natively supports multi-master
  \item Bus ownership is much more controlled than with I²C
  \item Gaining bus ownership involves a 2-way handshake between the
    currently active master and the one taking bus ownership
  \item 2 types of I3C masters:
    \begin{itemize}
    \item Main master: the master responsible for initializing the bus
    \item Secondary masters: masters that initially act as slaves and
      can at some point gain ownership of the bus
    \end{itemize}
  \item There can only be one main master on a given I3C bus
  \item But you can have several secondary masters
  \item Bus ownership handover can be requested by:
    \begin{itemize}
    \item an inactive master willing to control the bus
    \item the active master if it doesn't want to act as a master
      anymore (for example, when being suspended)
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{I3C protocol: want to learn more?}
  \begin{itemize}
  \item Very brief introduction to some of the I3C concepts
  \item Many pieces of information have been omitted
  \item If you want to know more, go check the I3C specification:
    \url{http://resources.mipi.org/mipi-i3c-v1-download}
  \end{itemize}
\end{frame}

\subsection{I3C support in Linux}

\begin{frame}{Supporting I3C in Linux}
  \begin{itemize}
  \item I3C is a bit tricky to categorize
    \begin{itemize}
    \item It is backward compatible with I²C devices
    \item But I3C device handling is completely different
    \end{itemize}
  \item Constraints:
    \begin{itemize}
    \item We must keep the existing I²C ecosystem unchanged (all I²C
      drivers and users should work as before)
    \item We should be able to support and expose I3C functionalities
    \end{itemize}
  \item Two options:
    \begin{enumerate}
    \item Extend the I²C framework to support I3C features
    \item Add an I3C framework and connect it to the I²C framework
    \end{enumerate}
  \item We went for option {\bf 2}
  \end{itemize}
\end{frame}

\begin{frame}{Linux I3C framework}
  \begin{center}
  \includegraphics[width=0.9\textwidth]{i3c-framework.pdf}
  \end{center}
\end{frame}

\begin{frame}{Linux I3C framework: design choices}
  \begin{itemize}
  \item Separate APIs for device drivers and I3C master controllers
  \item For each master controller an I3C and an I²C bus are created
  \item Both buses are connected through the controller parenting
  \item Device drivers are bound to devices based on the \code{DCR}
    or \code{PID} values
  \item IBIs are not exposed as regular IRQs (we tried this approach
    and it didn't fit well)
  \end{itemize}
\end{frame}

\begin{frame}{Linux I3C Device driver API: overview}
  \begin{itemize}
  \item Exposed in {\bf include/linux/i3c/device.h}
  \item Allows one to declare, register and unregister an I3C driver
  \item You can also register an hybrid I²C/I3C driver
  \item Provides a way to do SDR and HDR transfers (provided the
    device and master supports HDR modes)
  \item CCC commands are not exposed yet, since most of them are
    related to bus management (might change in the future if needed)
  \item Provides a way to register an IBI handler, and
    activate/deactivate the IBI
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Linux I3C Device driver API: declaring a driver}
\fontsize{8}{8}\selectfont
  \begin{minted}{c}
static int dummy_i3c_probe(struct i3c_device *dev)
{
	...
}

static int dummy_i3c_remove(struct i3c_device *dev)
{
	...
}

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);
  \end{minted}
\end{frame}

\begin{frame}[fragile]{Linux I3C Device driver API: SDR private transfers}
\fontsize{8}{8}\selectfont
  \begin{minted}{c}
	u8 reg = 0x5;
	u8 values[2] = {0x1, 0x2};
	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;

	...
  \end{minted}
\end{frame}

\begin{frame}[fragile]{Linux I3C Device driver API: DDR transfers}
\fontsize{8}{8}\selectfont
  \begin{minted}{c}
#define MYVENDOR_READ_COMMAND	HDR_VENDOR_READ_CMD(0)
...

        u16 data[4] = {};
	struct i3c_hdr_cmd hdrcmd = {
		.mode = I3C_HDR_DDR,
		.code = MYVENDOR_READ_COMMAND,
		.ndatawords = ARRAY_SIZE(data),
		.data.in = data,
	};

	ret = i3c_device_send_hdr_cmds(i3cdev, &hdrcmd, 1);
	if (ret)
		return ret;

	...
  \end{minted}
\end{frame}

\begin{frame}[fragile]{Linux I3C Device driver API: IBIs}
\fontsize{8}{8}\selectfont
  \begin{columns}
  \column{0.6\textwidth}
    \begin{minted}{c}
static void ibi_handler(struct i3c_device *dev,
                        const struct i3c_ibi_payload *payload)
{
	/* Called in a non-atomic context (workqueue) */
	...
}

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;
	...
}
    \end{minted}
  \column{0.5\textwidth}
    \begin{minted}{c}
static int remove(struct i3c_device *i3cdev)
{
	...
	i3c_device_disable_ibi(i3cdev);
	i3c_device_free_ibi(i3cdev);
	...
}
    \end{minted}
  \end{columns}

\end{frame}

\begin{frame}{Linux I3C Master controller driver API: overview}
  \begin{itemize}
  \item Exposed in {\bf include/linux/i3c/master.h}
  \item Allows one to register and unregister an I3C master controller
  \item Master controller drivers have to implement the
    \code{struct i3c_master_controller_ops} interface
  \item This interface tries to follow the I3C specification as much
    as possible
  \item Leaves a lot of freedom to drivers in how they deal with
    complex operations like DAA
  \item The framework provides generic helpers to help drivers
    implementing these operations
  \end{itemize}
\end{frame}

\begin{frame}{Linux I3C Master controller driver API: bus initialization}
  \begin{itemize}
  \item One of the first things controllers are asked to handle is the
    bus initialization
  \item The core
    \begin{itemize}
    \item parses information provided by the FW (currently, only DT
      parsing is supported)
    \item instantiates I²C and I3C device objects based on this
      definition (those devices are not registered to the device model)
    \end{itemize}
  \item And finally, the core calls the master controller
    \code{->bus_init()} method which is responsible for:
    \begin{itemize}
    \item Configuring the controller to take bus limitations into
      account (based on defined I²C devices)
    \item Pre-reserving dynamic addresses that are meant to be manually
      assigned before DAA
    \item Doing DAA to discover devices connected to the bus
    \item For each device discovered during DAA, the controller calls
      a core helper to add the new I3C device to the list of devices
    \end{itemize}
  \item Only after all these steps, both I3C and I²C devices are
     registered to the device model
  \end{itemize}
\end{frame}

\begin{frame}{Linux I3C Master controller driver API: various kind of transfers}
  \begin{itemize}
  \item One method for each:
    \begin{itemize}
    \item \code{->priv_xfers()} is for private SDR transfers
    \item \code{->send_hdr_cmds()} is for HDR transfers
    \item \code{->send_ccc_cmd()} is for CCC transactions
    \item \code{->i2c_xfers()} is for I²C transfers (used by the I²C
      \textrightarrow{} I3C glue)
    \end{itemize}
  \item There's an extra \code{->supports_ccc_cmd()}, since not all CCC
    commands are mandatory
  \item All these methods are working in a synchronous manner
  \item \code{->priv_xfers()} and \code{->send_hdr_cmds()} can do
    several transfers in one go using RepeatedStart instead of
    Stop+Start
  \end{itemize}
\end{frame}

\begin{frame}{Linux I3C Master controller driver API: IBIs}
  \begin{itemize}
  \item The master controller IBI interface follows the I3C device API:
    \begin{itemize}
    \item \code{->request_ibi()}: allocate resources to later handle IBIs
       coming from a specific device
    \item \code{->free_ibi()}: free resources allocated for IBIs coming
       from a specific device
    \item \code{->enable_ibi()}: enable IBIs coming from a device
    \item \code{->disable_ibi()}: disable IBIs coming from a device
    \item \code{->recycle_ibi_slot()}: recycle a payload slot that was
       previously used to deliver an IBI to a device driver. Called
       after the IBI handler returns
    \end{itemize}
  \item Design choices
    \begin{itemize}
    \item IBIs are delivered to the device driver in a workqueue
       context. Simply because IBIs may lead to other transmissions
       on the bus, and the API does not allow that in an atomic-context
    \item Still, you should refrain from doing everything from the IBI
       handler \textrightarrow{} it will prevent other IBIs from
       being delivered (maybe we should have a per-device workqueue...)
    \item IBI slots are pre-allocated, so you may lose some IBIs if the
       device driver is not handling them fast enough
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Linux I3C Master controller driver API: Hot-Join}
  \begin{itemize}
  \item Master controllers are likely to generate an interrupt when
    a Hot-Join request is received
  \item Master controller drivers will have to schedule a work (using
    the IBI workqueue) to start DAA
  \item They can use helpers to declare new devices after DAA
  \end{itemize}
\end{frame}

\begin{frame}{I3C support in Linux: the status}
  \begin{itemize}
  \item What has been implemented/tested?
  \begin{itemize}
    \item All the APIs described in the previous slides
    \item Master controller API has been tested with Cadence Master IP
    \item All Slave APIs have been tested using a dummy driver
      interacting with a dummy slave IP provided by Cadence
    \item Last version of the I3C patch series can be found here
      (reviews are welcome): \url{https://lkml.org/lkml/2017/12/14/406}
    \end{itemize}
  \item What's missing?
    \begin{itemize}
    \item I3C Multi-master with bus ownership handover procedure
    \item Slave controller API to support things like I3C gadget
    \item HDR-TSP/TSL. Couldn't test it since Cadence master controller
      IP does not support these modes
    \item We didn't have a real device driver, but this is being
      addressed (driver for an I3C gpio-expander will be part of the
      next version)
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}
  \centering
  \Huge
  Questions?\\
  \vspace{0.5cm}
  \huge
  Boris Brezillon\\
  \large
  {\em \insertemail}\\
  \vspace{0.5cm}
  Slides under CC-BY-SA 3.0\\
  \scriptsize
  \url{\insertslidesurl}
  \vspace{0.5cm}
  \begin{columns}
  \column{0.9\textwidth}
  \footnotesize
  \centering
  Support our crowdfunding campaign to develop\\
  an upstream Linux kernel driver for Allwinner VPU\\
  \url{https://bootlin.com/blog/allwinner-vpu-crowdfunding/}
  \column{0.1\textwidth}
  \includegraphics[height=2cm]{common/allwinnervpu.jpg}
  \end{columns}
\end{frame}

\end{document}
