\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}
\usepackage{media9}

\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{SPI Memories}
\conference{Embedded Linux Conference Europe, October 2018}
\authors{Miquèl Raynal \hfill Boris Brezillon}
\email{miquel@bootlin.com \hfill boris@bootlin.com}
\institute{Bootlin}
\slidesurl{https://bootlin.com/pub/conferences/2018/elce/raynal-spi-memories}

\begin{document}

\addtocontents{toc}{\protect\setcounter{tocdepth}{-1}}
\section{SPI Memory support in Linux and U-Boot}
\addtocontents{toc}{\protect\setcounter{tocdepth}{2}}

\begin{frame}{Miquèl Raynal}
  \begin{itemize}
  \item Embedded Linux engineer 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 NAND subsystem}
    \item {\bf Kernel support for various ARM SoCs}
    \end{itemize}
  \item Living in {\bf Toulouse}, south west of France
  \end{itemize}
\end{frame}

\begin{frame}{How we feel when talking about MTD}
  \begin{columns}
    \column{0.5\textwidth}
    \center\includegraphics[width=0.9\textwidth]{Childhood-nightmares.jpg}
    \null\vfill
        {\fontsize{5}{6}\selectfont Children's drawing center, Michal
          Wimmer\\\ \\\ \\}
        {\fontsize{10}{11}\selectfont MTD}
    \column{0.5\textwidth}
    \center\includegraphics[width=0.9\textwidth]{Van-Gogh-Starry-night.jpg}
    \null\vfill
        {\fontsize{5}{6}\selectfont Van Gogh's ``Starry Night''
          painting (Wikimedia Commons CC-BY-SA 3.0)\\\ \\}
        {\fontsize{10}{11}\selectfont Other subsystems}
  \end{columns}
\end{frame}

\begin{frame}{What is this talk about?}
  \begin{itemize}
  \item Understanding what SPI memories are and what protocol they use
  \item Looking at the Linux (and U-Boot) SPI memory stack (both past
    and present)
  \item Have a glimpse of future \code{spi-mem} framework evolutions
  \item Getting feedback from developers/users (if any in this room)
  \end{itemize}
\end{frame}

\begin{frame}{SPI bus evolutions: let's start small}
  \begin{columns}
  \column{0.6\textwidth}
  \begin{itemize}
  \item The SPI protocol started as a simple 4-wires protocol
    \begin{itemize}
    \item CS: Chip Select
    \item SCK: Serial Clock
    \item MISO: Master In Slave Out
    \item MOSI: Master Out Slave In
    \end{itemize}
  \item Relatively high frequency (usually above 10MHz)
  \item Full-duplex by nature
  \item Master-Slave approach:
    \begin{itemize}
    \item Only one master in control
    \item Each slave has its own CS line
    \end{itemize}
  \end{itemize}
  \column{0.4\textwidth}
  \includemedia[width=4.5cm,height=2.7cm,activate=pageopen,
    addresource=bbc-boomerang.mp4,
    flashvars={source=bbc-boomerang.mp4 &autoPlay=true &loop=true}]{}{VPlayer.swf}
  \null\vfill
      {\fontsize{5}{6}\selectfont Jeremy Clarkson entering a Peel P50,
        Top Gear, BBC}
  \end{columns}
\end{frame}

\begin{frame}{SPI bus evolutions: we need more juice!}
  \begin{columns}
    \column{0.5\textwidth}
  \begin{itemize}
  \item SPI is good, but not fast enough for some use cases, like storage
  \item Solutions to address this limitation
    \begin{itemize}
    \item Increase SCK frequency: some devices now support speed above
      100MHz
    \item Increase the I/O bus width: Dual SPI, Quad SPI and now Octo
      SPI
    \item DDR mode: data are sampled on both SCK edges
    \end{itemize}
  \item All these solutions come with extra cost:
    \begin{itemize}
    \item More complex to implement
    \item Quad and Octo modes require more pins
    \end{itemize}
  \end{itemize}
  \column{0.5\textwidth}
  \center\includegraphics[height=0.7\textwidth]{go-faster-photo-Vladislav-Maschl.jpg}
  \null\vfill
      {\fontsize{5}{6}\selectfont Photography: Vladislav Maschl. Quote:
        Mario Andretti, 1978 F1 world champion}
  \end{columns}
\end{frame}

\begin{frame}{Dual/Quad/Octo SPI: physical layer}
  \begin{itemize}
  \item Half-duplex
  \item I/O lines are bi-directional
  \item Number of I/O lines is device-specific
  \item The slave and master must agree on that (can be negotiated or
    hardcoded)
  \end{itemize}
  \begin{center}
  \includegraphics[height=0.2\textwidth]{spi-bus.pdf}
  \end{center}
  \begin{itemize}
  \item Controllers might use the CS lines as I/O lines $\Rightarrow$
    only 1 device on the bus
  \end{itemize}
\end{frame}

\begin{frame}{SPI memories: a pseudo-standard protocol 1/2}
  \begin{itemize}
  \item Standardizes how to communicate with a device
  \item Most of the time a memory device but not necessarily
  \item Every access is done through a SPI memory operation formed of:
%    \begin{itemize}
%    \item An opcode (1 or 2 bytes depending on the device and its state)
%    \item N address bytes (optional)
%    \item M dummy bytes (optional)
%    \item P data bytes (optional)
%    \end{itemize}
  \end{itemize}
  \center\includegraphics[height=0.35\textwidth]{spi-mem-protocol.pdf}
\end{frame}

\begin{frame}{SPI memories: a pseudo-standard protocol 2/2}
  \begin{itemize}
  \item The opcode determines
    \begin{itemize}
    \item The number of address and dummy bytes
    \item The direction of the data transfer (if any)
    \item The number of I/O lines used for each element
    \end{itemize}
  \item Command set is device specific
  \end{itemize}
\end{frame}

\begin{frame}{SPI memories: standard command sets}
  \begin{itemize}
  \item There are currently two distinct standard command sets
    \begin{itemize}
    \item SPI NAND
    \item SPI NOR
    \end{itemize}
  \item Standardizes the following operations:
    \begin{itemize}
    \item Read/Write accesses
    \item Erase operations
    \item Device identification
    \item Accesses to internal registers
    \end{itemize}
  \item Also standardizes some registers and their contents:
    \begin{itemize}
    \item STATUS
    \item CONFIGURATION
    \end{itemize}
  \item Vendor specific operations/registers can be added on top
  \end{itemize}
\end{frame}

\begin{frame}{SPI memories: NOR vs. NAND command set}
    \begin{itemize}
    \item Example: Read operation
    \end{itemize}
  \begin{center}
  \includegraphics[width=1\textwidth]{spi-mem-command-sets-examples.pdf}
  \end{center}
\end{frame}

\section{SPI memories support in Linux}

\begin{frame}{SPI memories support in Linux: a bit of history}
  \begin{itemize}
  \item Initially supported as simple SPI device drivers
  \item Most of the time placed in \kdir{drivers/mtd/devices}
  \item Drivers were manually building SPI memory operations using
    \ksym{spi_message}s made of several \ksym{spi_transfer}s
  \item Apparition of SPI NORs and advanced SPI controllers forced us
    to reconsider this approach
    \begin{itemize}
    \item Creation of a \code{spi-nor} subsystem to deal with the SPI NOR
      command set
    \item Creation of a \code{spi_nor} interface to be implemented by
      advanced SPI controller drivers
    \item Generic SPI NOR controller driver used to interface with
      generic SPI controllers (\kfile{drivers/mtd/devices/m25p80.c})
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{The SPI NOR stack}
  \begin{center}
  \includegraphics[height=0.5\textwidth]{spi-nor-stack.pdf}
  \end{center}
\end{frame}

\begin{frame}{SPI memories support in Linux: recent changes}
  \begin{itemize}
  \item The approach taken to support SPI NORs worked fine until people
    decided to support SPI NANDs
  \item Most SPI controllers are memory agnostic and can thus be
    interfaced with any kind of device (NOR, NAND, SRAM, and even
    regular SPI devices)
  \item Problems:
    \begin{itemize}
    \item NOR and NAND command sets are totally different
    \item NOR and NAND devices have different constraints and can't be
      handled the same way
    \item We want to have the same SPI controller driver, no matter the
      device it's interfaced with
    \item We don't want to create a custom interface per-memory type
    \end{itemize}
  \item Solution:
    \begin{itemize}
    \item Move the SPI memory protocol bits to the SPI subsystem
    \item Let the SPI NOR and SPI NAND layers interface with this SPI
      memory layer
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{The SPI memory stack}
  \begin{center}
  \includegraphics[height=0.4\textwidth]{spi-mem-stack.pdf}
  \end{center}
\end{frame}

\begin{frame}{The SPI memory stack: read example}
  \begin{center}
  \includegraphics[width=0.95\textwidth]{spi-mem-stack-example.pdf}
  \end{center}
\end{frame}

\section{SPI memories support in U-Boot}

\begin{frame}{U-Boot: Almost the same framework}
  \begin{itemize}
  \item Port of the \code{spi-mem}/\code{spi-nand} framework
  \item Internal rework to use most of the MTD stack instead of the
    internal glue that has been added over the releases
  \item Cleaner partition handling not even in Linux yet!
  \item Merged in v2018.11-rc2
  \end{itemize}
\end{frame}

\begin{frame}{U-Boot: the \code{mtd} command}
  \begin{itemize}
  \item Existing MTD devices commands: \code{sf}, \code{nand}, \code{onenand}
  \item But also: \code{mtdparts}
    \begin{itemize}
    \item Shall we add a \code{spinand} one?
    \end{itemize}
  \item MTD already abstracts the type of device for the user
  \item Creation of a generic command: \code{mtd}
    \begin{itemize}
    \item Similar operations than before
    \item U-Boot Driver-Model compliant
    \item \code{help mtd}
    \item The above commands should be deprecated (on the long run)
      \begin{itemize}
        \item \code{mtdparts}/\code{mtdids} variables still useful!
        \item Any \code{mtd} command will check for a change in these
          variables, in this case, MTD partitions will be updated
      \end{itemize}
    \end{itemize}
  \end{itemize}
\end{frame}

\section{SPI memories: future development}

\begin{frame}{SPI memories support in Linux: the next steps}
  \begin{itemize}
  \item Support direct mapping
    \begin{itemize}
    \item Supported by most advanced SPI controllers
    \item Optimizes I/Os
    \item An interface has been proposed here \\\url{http://lists.infradead.org/pipermail/linux-mtd/2018-June/081460.html}
    \end{itemize}
  \item Convert all SPI NOR controller drivers to SPI controller
    drivers implementing the SPI memory interface
  \item Try not to reproduce our previous mistakes
    \begin{itemize}
    \item Extend the SPI memory interface with extra care
    \item Try to stay memory-agnostic
    \end{itemize}
  \item Extra features
    \begin{itemize}
    \item XIP?
    \item Other optimizations?
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{SPI memories: a few words about the dirmap API}
  \begin{center}
  \includegraphics[height=0.43\textwidth]{spi-mem-dirmap.pdf}
  \end{center}
\end{frame}

\begin{frame}{SPI memories: a few words about the dirmap API}
  \begin{itemize}
  \item A direct mapping instance has 3 properties:
    \begin{itemize}
    \item The memory device offset it's pointing it
    \item The size of the mapping
    \item A \code{spi_mem_op} template to execute when the dirmap is
      accessed
    \end{itemize}
  \item Implementation is controller specific
  \item Four methods to implement:
    \begin{itemize}
    \item \code{->create_dirmap()}: create a direct mapping
    \item \code{->destroy_dirmap()}: destroy a direct mapping
    \item \code{->dirmap_read()}: do a read access on the dirmap object
    \item \code{->dirmap_write()}: do a read access on the dirmap object
    \end{itemize}
  \item All methods are optional, when unimplemented the framework falls
    back to regular \code{->exec_op()} operations
  \item SPI mem users can create, destroy and do read/write accesses on
    dirmap using the \code{spi_mem_dirmap_{create,destroy,read,write}()}
    functions
  \end{itemize}
\end{frame}

\begin{frame}{SPI NOR: what's in the pipe?}
  \begin{columns}
  \column{0.6\textwidth}
  \begin{itemize}
  \item Add support for non-uniform erase sizes
    \newline (Tudor Ambarus, merged in 4.20)
  \item Convert Atmel/Microchip and Freescale SPI NOR controller
    drivers to the SPI mem interface (Piotr Bugalski and
    Frieder Schrempf)
  \item Use the SPI mem direct mapping API to get better performance
  \item Finally move the m25p80 driver in \kdir{drivers/mtd/spi-nor} and
    rename it \newline
    \href{http://patchwork.ozlabs.org/patch/982925/}
         {\textit{mtd: spi-nor: Move m25p80 code in spi-nor.c}}
  \end{itemize}
  \column{0.4\textwidth}
  \center\includemedia[width=4.5cm,height=2.6cm,activate=pageopen,
    addresource=pipe.mp4,
    flashvars={source=pipe.mp4 &autoPlay=true &loop=true}]{}{VPlayer.swf}
  \end{columns}
\end{frame}

\begin{frame}{SPI NAND: what's in the pipe?}
  \begin{itemize}
  \item Implement generic support for on-flash bad block table
    parsing/update
  \item Parse the ONFI parameter table when available?
  \item Define a generic ECC engine interface so that SPI NANDs without
    on-die ECC can be used with SoCs providing such an ECC engine (or
    with the software ECC implementation)
  \item Use the SPI mem direct mapping API to get better performance
  \item Add support for more chips \newline
    \href{http://patchwork.ozlabs.org/patch/979945/}
         {\textit{mtd: spinand: winbond: Add support for W25N01GV}}
    \item The SPI NAND staging driver is going to be removed in the
    next release \newline
    \href{http://patchwork.ozlabs.org/patch/987907/}
         {\textit{staging: Remove the mt29f\_spinand driver}}
  \end{itemize}
\end{frame}

\begin{frame}
  \centering
  \Huge
  Questions? Suggestions? Comments?\\
  \vspace{0.5cm}
  \huge
  Miquèl Raynal and Boris Brezillon\\
  \large
  \vspace{0.5cm}
  \hspace{2.6cm}\code{miquel@bootlin.com} and \code{boris@bootlin.com}
  \vspace{0.5cm}
  \newline Slides under CC-BY-SA 3.0\\
  \scriptsize
  \url{https://bootlin.com/pub/conferences/2018/elce/raynal-spi-memories}
\end{frame}

\end{document}
