\documentclass[aspectratio=169,obeyspaces,spaces,hyphens]{beamer}
\usepackage[utf8]{inputenc}
\usepackage{minted}

\mode<presentation>
\usetheme{Bootlin}

\newcommand{\codehack}[1]{{\usebeamercolor[fg]{code} {\tt #1}}}

\title{Using DT overlays to support the C.H.I.P.'s capes}
\authors{Antoine Ténart}
\institute{Bootlin}

\usepackage{hyperref}

\newcounter{lessonno}

\begin{document}

\begin{frame}{Embedded Linux Conference 2016}
  \huge
  \begin{center}
  Using DT overlays to support the C.H.I.P.'s capes\\
  \end{center}
\end{frame}

\begin{frame}{Antoine Ténart}
  \begin{itemize}
  \item antoine.tenart@bootlin.com
  \item Embedded Linux engineer at {\bf Bootlin}.
    \begin{itemize}
    \item Embedded Linux specialists.
    \item Development, consulting and training (materials freely
      available under a Creative Commons license).
    \item \url{http://bootlin.com}
    \end{itemize}
  \item Contributions
    \begin{itemize}
    \item Kernel support for the Marvell Berlin ARM SoCs.
    \item Kernel support for the Annapurna Labs ARM64 Alpine v2
      platform.
    \end{itemize}
  \item Living in {\bf Toulouse}, south west of France.
  \end{itemize}
\end{frame}

\begin{frame}
\tableofcontents
\end{frame}

\begin{frame}{What is this talk about?}
  \begin{itemize}
  \item Giving an overview of how to handle capes in the kernel, and
    describing the requirements.
  \item Describing the solution we went for.
  \item Digging into the different parts of our solution.
  \end{itemize}
\end{frame}

\subsection{Context}

\begin{frame}{Context: the CHIP, the capes and us}
  \begin{columns}
    \column{0.5\textwidth}
  \begin{itemize}
  \item The {\bf CHIP}: a 9\$ board by {\bf NextThing Co.} built
    around the Allwinner R8 SoC (Cortex-A8).
  \item Funded thanks to a Kickstarter campaign in 2015.
  \item {\bf Bootlin} working on the CHIP kernel support.
  \item Was designed from the beginning to have adapters:
    \begin{itemize}
    \item VGA adapter.
    \item HDMI adapter.
    \item Pocket CHIP.
    \end{itemize}
  \end{itemize}
    \column{0.5\textwidth}
  \begin{center}
  \includegraphics[scale=0.4]{pocket_chip.png}
  \end{center}
  \end{columns}
\end{frame}

\begin{frame}{The CHIP expander}
  \begin{center}
  \includegraphics[width=0.6\textwidth]{chip_pinout.png}
  \end{center}
\end{frame}

\begin{frame}{Cape definition \& benefits}
  \begin{itemize}
  \item An adapter to extend board functionalities.
  \item Some I/Os are muxable: different capes for different usages!
  \item Prototype development made easy.
  \item DIY projects.
  \item Everyone can design and sell his own capes.
  \end{itemize}
\end{frame}

\begin{frame}{Requirements}
  \begin{itemize}
  \item Capes can be changed.
  \item Not a finite set of capes.
    \begin{itemize}
    \item The capes need to be auto-detected at boot time.
    \end{itemize}
  \item Capes can be stacked.
    \begin{itemize}
    \item The auto-detection mechanism should be able to enumerate the
      capes.
    \end{itemize}
  \item This should work {\bf without} the user intervention!
  \end{itemize}
\end{frame}

\subsection{Overview}

\begin{frame}{The header}
  \begin{itemize}
  \item Used to organize the cape's description.
  \item Needs a magic value to differentiate it from random data.
  \item Capes can have different versions or revisions.
  \item Allows each cape to store specific data.
  \item This header is stored in an onboard EEPROM.
    \begin{itemize}
    \item Easy to read from / write to.
    \item Cheap.
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{The header format}
  \begin{minted}{c}
struct cape_chip_header {
        u32     magic;     /* must be 0x43484950 "CHIP" */
        u8      version;   /* spec version */
        u32     vendor_id;
        u16     product_id;
        u8      product_version;
        char    vendor_name[32];
        char    product_name[32];
        u8      rsvd[36];  /* rsvd for future versions */
        u8      data[16];  /* per-cape specific */
} __packed;
  \end{minted}
\end{frame}

\begin{frame}{Cape identification}
  \begin{itemize}
  \item Each pin used to communicate to the EEPROM cannot be reused:
    \begin{itemize}
    \item We wanted a bus with the lowest number of lines.
    \end{itemize}
  \item We did not need a high speed bus:
    \begin{itemize}
    \item Only used to read the cape's header.
    \end{itemize}
  \item The bus must support enumeration, to connect more than one
    cape.
  \item We chose the 1-wire bus.
  \end{itemize}
\end{frame}

\begin{frame}{Kernel hardware description}
  \begin{itemize}
  \item The CHIP is based on an ARM Cortex-A8.
  \item The hardware description is now done with Device Trees in the
    upstream kernel, for ARM based boards.
  \item Describe the SoC IPs, and which ones to enable (and configure)
    for a given board.
  \item The proper solution would be to modify this device tree.
    \begin{itemize}
    \item This can be done with device tree overlays!
    \end{itemize}
  \end{itemize}
\end{frame}

\subsection{The 1-wire bus}

\begin{frame}{Overview}
  \begin{itemize}
  \item Single signal.
  \item Low-speed data and signaling.
  \item Only two wires needed:
    \begin{itemize}
    \item Data.
    \item Ground.
    \end{itemize}
  \item Uses a capacitor to store charge and power the device when the
    data line is active.
    \begin{itemize}
    \item The capacitor needs to be charged!
    \item We had weird side effects because of this in U-Boot → the
      line needs to be pulled long enough firstly.
    \end{itemize}
  \item Two speed modes: normal and overdrive (speed x10).
  \item Four operations: \code{read}, \code{write 0}, \code{write 1}
    and \code{reset}.
  \item Can be used over a GPIO.
    \begin{itemize}
    \item \kfile{drivers/w1/master/w1-gpio.c}
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Read operation}
  \begin{columns}
    \column{0.5\textwidth}
  \begin{enumerate}
  \item Drive the bus low.
  \item Wait 6µs.
  \item Release the bus.
  \item Wait 9µs.
  \item Sample the bus to read the bit send by the slave.
  \item Wait 55µs.
  \end{enumerate}
    \column{0.5\textwidth}
  \begin{center}
  \includegraphics[scale=0.4]{read.png}
  \end{center}
  \end{columns}
\end{frame}

\begin{frame}{Write operation}
  \begin{columns}
    \column{0.5\textwidth}
  \begin{itemize}
  \item To write 0:
    \begin{enumerate}
    \item Drive the bus low.
    \item Wait 60µs.
    \item Release the bus.
    \item Wait 10µs.
    \end{enumerate}
  \item To write 1:
    \begin{enumerate}
    \item Drive the bus low.
    \item Wait 6µs.
    \item Release the bus.
    \item Wait 64µs.
    \end{enumerate}
  \end{itemize}
    \column{0.5\textwidth}
  \includegraphics[scale=0.3]{write.png}
  \end{columns}
\end{frame}

\begin{frame}{Reset operation}
  Reset the bus slave devices and ready them for a command.
  \begin{enumerate}
  \item Drive the bus low.
  \item Wait 480µs.
  \item Release the bus.
  \item Wait for 70µs.
  \item Sample the bus:
    \begin{itemize}
    \item 0: one or more slave devices present.
    \item 1: no slave device present.
    \end{itemize}
  \end{enumerate}
\end{frame}

\begin{frame}{Slave devices numeration}
  \begin{itemize}
  \item Each devices have a 64-bit unique identifier.
  \item Used to address them individually by the master.
  \item Binary tree search.
  \end{itemize}
\end{frame}

\begin{frame}{Kernel support}
  \begin{itemize}
  \item \kdir{drivers/w1}
  \item Not actively maintained.
  \item No interface to the 1-wire framework.
    \begin{itemize}
    \item Slave drivers should be in \kdir{drivers/w1/slaves}
    \item Difficult to use the bus from outside the subsystem.
    \end{itemize}
  \end{itemize}
\end{frame}

\subsection{Introduction to Device Tree Overlays}

\begin{frame}{Overview}
  \begin{itemize}
  \item The device tree is a data structure.
  \item It's organized as a tree: there are nodes.
  \item Not aimed to be generated dynamically.
  \item Loaded at boot time by the bootloader, or embedded in the
    kernel image.
  \item Nice for describing a SoC or a board\dots but not suitable for
    hot-pluggable stuff.
  \end{itemize}
\end{frame}

\begin{frame}{Device Tree Overlays}
  \begin{itemize}
  \item Allows modification of the device tree at runtime:
    \begin{itemize}
    \item To add a node.
    \item To modify a property.
    \end{itemize}
  \item Not persistent across reboots.
  \item Examples:
    \begin{itemize}
    \item Turn on or off an hardware block by updating a node
      \code{status} property.
    \item Modifying the pinmux.
    \item Adding a hardware controller description.
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Upstream status}
  \begin{itemize}
  \item In-kernel support: \code{CONFIG_OF_DYNAMIC}.
  \item No U-Boot support (at the time of writing)\dots but patches
    sent while in the plane on our way to ELC :-)
  \item DTC (device tree compiler) needs a patch to enable dynamic
    phandle resolution.
    \begin{itemize}
    \item Required to use device tree overlays.
    \item Still not available upstream.
    \item This means the one used by the kernel build system cannot
       handle overlays!
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Overlay example: adding a new node}
  \begin{minted}[fontsize=\tiny]{c}
/dts-v1/;
/plugin/;

/ {
        compatible = "nextthing,chip","allwinner,sun5i-r8";

        fragment@0 {
                target-path = "/soc@01c00000";

                __overlay__ {
                        leds {
                                compatible = "gpio-leds";
                                pinctrl-names = "default";
                                pinctrl-0 = <&chip_test_led>;

                                led0 {
                                        label = "Test led";
                                        gpios = <&pio 3 4 0>; /* PD4 */
                                        default-state = "on";
                                };
                        };
                };
        };
};
  \end{minted}
\end{frame}

\begin{frame}[fragile]{Overlay example: modifying a property}
  \begin{minted}{c}
/dts-v1/;
/plugin/;

/ {
       compatible = "nextthing,chip","allwinner,sun5i-r8";

       fragment@0 {
               target = <&mmc0>;
               __overlay__ {
                       status = "okay";
               };
       };
};
  \end{minted}
\end{frame}

\begin{frame}{Targets}
  \begin{itemize}
  \item To be applied a device tree overlay fragment needs a target.
  \item Describes where to apply the changes.
  \item Two possibilities:
    \begin{itemize}
    \item \code{target-path}: the argument is a path.
    \item \code{target}: the argument is a phandle.
    \end{itemize}
  \item When using \code{target}, the phandle resolution should be
    dynamic.
  \end{itemize}
\end{frame}

\begin{frame}{Compiling}
  \begin{itemize}
  \item \code{dtc -O dtb -o foo.dtb -@ foo.dts}
  \item The \code{-@} option comes from an out-of-tree patch.
  \item It will generates extra nodes under the root node:
    \begin{itemize}
    \item \code{__symbols__} in the base tree.
    \item \code{__symbols__}, \code{__fixups__} and
      \code{__local_fixups__} in the overlay.
    \item Contains metadata used for symbol resolution.
    \end{itemize}
  \item \code{/plugin/} marks device tree overlay.
  \end{itemize}
\end{frame}

\subsection{Example: the base tree}

\begin{frame}[fragile]{Base tree}
  \begin{minted}{c}
/dts-v1/;

/ {     
        compatible = "example";
        foo = <&bar>;

        bar: bar@0 {
                compatible = "example,bar";
        };
};
  \end{minted}
\end{frame}

\begin{frame}[fragile]{Device Tree object without dynamic symbols}
  \begin{minted}{c}
/dts-v1/;

/ {
    compatible = "example";
    foo = <0x00000001>;

    bar@0 {
        compatible = "example,bar";
        linux,phandle = <0x00000001>;
        phandle = <0x00000001>;
    };
};
  \end{minted}
\end{frame}

\begin{frame}[fragile]{Device Tree object with dynamic symbols}
  \begin{minted}{c}
/dts-v1/;
/ {
    compatible = "example";
    foo = <0x00000001>;
    bar@0 {
        compatible = "example,bar";
        linux,phandle = <0x00000001>;
        phandle = <0x00000001>;
    };

    __symbols__ {
        bar = "/bar@0";
    };
};
  \end{minted}
\end{frame}

\subsection{Example: the overlay}

\begin{frame}[fragile]{Device Tree Overlay}
  \begin{minted}{c}
/dts-v1/;
/plugin/;
/ {
        compatible = "example";
        fragment@0 {
                target-path = "/";

                __overlay__ {
                        quux = <&qux>;

                        qux: qux@0 {
                                property = <&foo>;
                        };  
                };  
        };  
};
  \end{minted}
\end{frame}

\begin{frame}[fragile]{Device Tree Overlay Object}
  \begin{minted}{c}
/dts-v1/;
/ {
    compatible = "example";
    fragment@0 {
        target-path = "/";
        __overlay__ {
            quux = <0x00000001>;
            qux@0 {
                property = <0xdeadbeef>;
                linux,phandle = <0x00000001>;
                phandle = <0x00000001>;
            };
        };
    };
  \end{minted}
\end{frame}


\begin{frame}[fragile]
  \begin{minted}{c}
    __symbols__ {
        qux = "/fragment@0/__overlay__/qux@0";
    };
    __local_fixups__ {
        fragment@0 {
            __overlay__ {
                quux = <0x00000000>;
            };
        };
    };
    __fixups__ {
        foo = "/fragment@0/__overlay__/qux@0:property:0";
    };
};
  \end{minted}
\end{frame}

\subsection{phandle resolution}

\begin{frame}{phandle resolution}
  \begin{enumerate}
  \item Get the max base tree phandle value, and add \code{1}.
  \item Ajdust the overlay phandle values, then use the
    \code{__local_fixups__} node to fix local references.
  \item Use the \code{__fixups__} node to resolve the overlay
    phandles referencing objects in the base tree.
  \item Update these references.
  \end{enumerate}
\end{frame}

\subsection{Applying a Device Tree Overlay}

\begin{frame}{Applying Device Tree Overlays 1/4}
  \begin{itemize}
  \item \kfunc{request_firmware}
  \item Load a firmware into memory.
  \item The firmware is actually a Device Tree Overlay blob, stored in
    \code{/lib/firmware/}.
  \item Takes the name of the firmware as an argument.
    \begin{itemize}
    \item It should be guessed from the cape's header.
    \item \code{dip-<vendor_id>-<product_id>-<product_version>.dtbo}
    \item If not found, fallback to: \code{dip-<vendor_id>-<product_id>.dtbo}
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Applying Device Tree Overlays 2/4}
  \begin{itemize}
  \item \kfunc{of_fdt_unflatten_tree}
    \begin{itemize}
    \item Unflatten the overlay loaded previously.
    \item Create a tree of device nodes from a blob: the live tree
      format.
    \end{itemize}
  \item \kfunc{of_resolv_phandles}
    \begin{itemize}
    \item Resolves the phandles against the live tree.
    \item Dynamic resolution, using nodes added thanks to \code{dtc}'s
      \code{-@} option.
    \end{itemize}
  
  \end{itemize}
\end{frame}

\begin{frame}{Applying Device Tree Overlays 3/4}
  \begin{itemize}
  \item At this point, we can use the \code{of_*} helpers.
  \item Time to make some checks!
  \item Is the overlay compatible with the machine used?
  \end{itemize}
\end{frame}

\begin{frame}{Applying Device Tree Overlays 4/4}
  \begin{itemize}
  \item \kfunc{of_overlay_create}
  \item Creates and applies an overlay.
  \item Keeps track of the overlay applied.
  \item Can be reverted with \kfunc{of_overlay_destroy}
    \begin{itemize}
    \item When removing stacked overlays, this needs to be done in
      reverse order.
    \end{itemize}
  \end{itemize}
\end{frame}

\subsection{The cape manager}

\begin{frame}{Overview}
  \begin{itemize}
  \item Responsible for detecting a cape, identifying it and applying
    the corresponding overlay.
  \item Uses all components described before:
    \begin{itemize}
    \item The 1-wire bus.
    \item The EEPROM in which the cape's header is stored.
    \item The device tree overlay mechanism.
    \end{itemize}
  \item Implemented in the kernel space.
  \end{itemize}
\end{frame}

\begin{frame}{The cape manager 1/2}
  \begin{itemize}
  \item We patched the 1-wire framework to add callbacks when a new
    device is detected on the bus.
    \begin{itemize}
    \item Allows to read the header stored on the cape's EEPROM as
      soon as the cape is detected.
    \end{itemize}
  \item The EEPROM driver for the DS2431 was available in
    \kdir{drivers/w1/slaves/}
  \item Cannot be used outside of the 1-wire framework!
  \item We redefined its read function in the cape manager.
  \end{itemize}
\end{frame}

\begin{frame}{The cape manager 2/2}
  \begin{itemize}
  \item Works fine for most uses.
  \item Our first test was with a LED and a PWM.
  \item This can't work when adding / enabling devices handled by
    subsystems without hotplug support.
    \begin{itemize}
    \item Like DRM/KMS.
    \end{itemize}
  \item Quick solution: add the overlay support in the bootloader.
    \begin{itemize}
    \item Maxime Ripard patched U-Boot.
    \item Not yet upstreamed.
    \end{itemize}
  \item Would be better to patch directly DRM/KMS.
  \end{itemize}
\end{frame}

\begin{frame}{Summary}
  \begin{enumerate}
  \item A new salve device is detected on the 1-wire bus.
  \item If the new device family is recognized by the cape manager, a
    callback is called.
  \item The cape manager reads the header stored on the EEPROM.
  \item The cape manager parses the header and decides which cape to
    load.
  \item A DT overlay is loaded from userspace.
  \item The overlay is applied on the live tree.
  \end{enumerate}
  \begin{center}
  \includegraphics[scale=0.4]{summary.png}
  \end{center}
\end{frame}

\subsection{Current status}

\begin{frame}{Status}
  \begin{itemize}
  \item Implemented recently.
  \item Solution not fully upstreamed yet.
  \item The best thing would be to also support other boards with
    capes, like the Beaglebone family.
  \item DTC still needs to be patched.
    \begin{itemize}
    \item We're not sure what to do.
    \end{itemize}
  \item We plan to send our patches to the Linux and U-Boot
    communities.
  \end{itemize}
\end{frame}

\begin{frame}
  \begin{center}
  \vspace{1cm}
  \Huge
  Thanks! Questions?\\
  \vspace{3cm}
  \large
  Slides under CC-BY-SA 3.0\\
  \vspace{0.5cm}
  \scriptsize
  https://bootlin.com/pub/conferences/2016/elc/tenart-chip-overlays/
  \end{center}
\end{frame}

\end{document}
