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

\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{An Overview of the DMAEngine Subsystem}
\conference{Embedded Linux Conference 2015}
\authors{Maxime Ripard}
\email{maxime@bootlin.com}
\institute{Bootlin}
\slidesurl{http://bootlin.com/pub/conferences/2015/elc/ripard-dmaengine}

\usepackage{hyperref}

\begin{document}

\section{An Overview of the DMAEngine Subsystem}

\begin{frame}{Maxime Ripard}
  \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 {\bf training}, Linux driver development
      training and Android system development training, with materials
      freely available under a Creative Commons license.
    \item \url{http://bootlin.com}
    \end{itemize}
  \item Contributions
    \begin{itemize}
    \item {\bf Kernel support for the sunXi SoCs} from Allwinner
    \item Contributor to few open-source projects, {\bf Buildroot}, an
      open-source, simple and fast embedded Linux build system,
      {\bf Barebox}, a modern bootloader.
    \end{itemize}
  \item Living in {\bf Toulouse}, south west of France
  \end{itemize}
\end{frame}

\subsection{Introduction}

\begin{frame}
  \frametitle{Device DMA vs...}
  \begin{center}
    \includegraphics[scale=0.35]{peripheral-dma.pdf}
  \end{center}
\end{frame}

\begin{frame}
  \frametitle{... DMA Controllers}
  \begin{center}
    \includegraphics[scale=0.35]{dumb-dma-controller.pdf}
  \end{center}
\end{frame}

\begin{frame}
  \frametitle{Transfer Width}
  \begin{center}
    \includegraphics[scale=0.35]{transfer-width.pdf}
  \end{center}
\end{frame}

\begin{frame}
  \frametitle{Burst Size}
  \begin{center}
    \includegraphics[scale=0.35]{burst-size.pdf}
  \end{center}
\end{frame}

\begin{frame}
  \frametitle{Scatter Gather}
  \begin{center}
    \includegraphics[scale=0.35]{scatter-gather.pdf}
  \end{center}
\end{frame}

\begin{frame}
  \frametitle{Scatter Gather Descriptors}
  \begin{center}
    \includegraphics[scale=0.35]{scatter-gather-descriptors.pdf}
  \end{center}
\end{frame}

\begin{frame}
  \frametitle{Cyclic Transfers}
  \begin{center}
    \includegraphics[scale=0.35]{cyclic-transfers.pdf}
  \end{center}
\end{frame}

\begin{frame}
  \frametitle{Realistic DMA Controller}
  \begin{center}
    \includegraphics[scale=0.35]{realistic-dma-controller.pdf}
  \end{center}
\end{frame}

\subsection{Linux Support}

\begin{frame}
  \frametitle{APIs}
  \begin{itemize}
  \item DMAEngine
    \begin{itemize}
    \item Merged in 2006, in 2.6.18
    \item Subsystem to handle memory-to-device transfers
    \end{itemize}
  \item Async TX
    \begin{itemize}
    \item Merged in 2007, in 2.6.23
    \item Initially part of the raid5 code to support the XScale
      offload engines
    \item Subsystem to handle memory to memory operations (memcpy,
      XOR, etc.)
    \item Implemented on top of dmaengine, but takes many
      shortcuts, instead of being a real client.
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{Slave consumer API}
  \begin{enumerate}
  \item Request a channel: \code{dma_request_channel}, or one of its
    variants
  \item Configure the channel for our use:
    \code{dmaengine_slave_config}
  \item Get a transaction descriptor for our transfer:
    \code{dmaengine_prep_*}
  \item Put the transaction in the driver pending queue:
    \code{dmaengine_submit}
  \item Issue pending requests (blocks and calls back your driver to
    give an update on the transfer status):
    \code{dmaengine_issue_pending}
  \end{enumerate}
\end{frame}

\subsection{Slave Controller Drivers}

\begin{frame}
  \frametitle{\code{struct dma_device} and its Fields}
  \begin{itemize}
  \item DMAEngine, like any framework, relies on a structure you have
    to fill with various pieces of information in order to do its job
    properly.
  \item Mostly:
    \begin{description}
    \item[channels] Initialized list of the channels supported by the
      driver, of the size of the number of channels supported by your
      driver
    \item[*\_align] Alignment in bytes for the Async TX buffers
    \end{description}
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{DMA Transfer Types 1/2}
  \begin{itemize}
  \item The next step is to set which transfer types your driver
    supports
  \item This is done through the function \code{dma_cap_set}, which
    takes various flags as an argument:
    \begin{itemize}
    \item \code{DMA_MEMCPY}
      \begin{itemize}
      \item Memory to memory copy
      \end{itemize}
    \item \code{DMA_SG}
      \begin{itemize}
      \item Memory to memory scatter gather
      \end{itemize}
    \item \code{DMA_INTERLEAVE}
      \begin{itemize}
      \item Memory to memory interleaved transfer
      \end{itemize}
    \item \code{DMA_XOR}
      \begin{itemize}
      \item Memory to memory XOR
      \end{itemize}
    \item \code{DMA_XOR_VAL}
      \begin{itemize}
      \item Memory buffer parity check using XOR
      \end{itemize}
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{DMA Transfer Types 2/2}
  \begin{itemize}
  \item \code{DMA_PQ}
    \begin{itemize}
    \item Memory to memory P+Q computation
    \end{itemize}
  \item \code{DMA_PQ_VAL}
    \begin{itemize}
    \item Memory buffer parity check using P+Q
    \end{itemize}
  \item \code{DMA_INTERRUPT}
    \begin{itemize}
    \item The device is able to generate a dummy transfer that will
      generate interrupts
    \end{itemize}
  \item \code{DMA_SLAVE}
    \begin{itemize}
    \item Memory to device transfers
    \end{itemize}
  \item \code{DMA_CYCLIC}
    \begin{itemize}
    \item The device is able to handle cyclic transfers
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{Weird Transfer Types}
  \begin{itemize}
  \item \code{DMA_PRIVATE}
    \begin{itemize}
    \item Async TX doesn't go through \code{dma_request_channel} but
      circumvents it, and just starts using any random channel it can.
    \item It does so unless you set this flag
    \end{itemize}
  \item \code{DMA_ASYNC_TX}
    \begin{itemize}
    \item Set by the core when you support all Async TX transfer types
    \item Used only if \code{ASYNC_TX_ENABLE_CHANNEL_SWITCH} is
      enabled
    \item Used by \code{dma_find_channel}, which is a non-exclusive
      equivalent of \code{dma_request_channel}, used only by Async TX
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{Channels Resources Allocation}
  \begin{itemize}
  \item \code{device_alloc_chan_resources} and
    \code{device_free_chan_resources}
  \item Called by the framework when your channel is first requested
  \item Allows to allocate custom resources for your channel, and free
    them when you're done
  \item Optional (since 3.20)
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{Transaction Descriptor Retrieval Functions}
  \begin{itemize}
  \item \code{device_prep_dma_*}
  \item Optional, but have to match the transfer types you declared
  \item Should create both the software descriptor, for Linux and
    clients to identify the transfer, and the hardware descriptor
    matching it for the dma controller.
  \item Should also ensure that the parameters of this transfer match
    what the driver supports
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{Submitting Pending Jobs}
  \begin{itemize}
  \item \code{device_issue_pending}
  \item Should take the first descriptor of the transaction and start
    it
  \item Should go through all the descriptors in the list, notifying
    the client using an optional callback of the status of the
    transfer
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{Transfer Status Reporting}
  \begin{itemize}
  \item \code{device_tx_status}
  \item Reports the current state of a given transaction descriptor
  \item Does so using the \code{dma_set_residue} function, and returns
    only a flag saying whether it's done or in progress.
  \item This is where the granularity we used earlier comes into
    action.
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{Channel configuration}
  \begin{itemize}
  \item \code{device_control}
  \item Takes an additional flag, to give the type of control to
    do on the channel
    \begin{itemize}
    \item \code{DMA_PAUSE}
      \begin{itemize}
      \item Pause a given channel
      \end{itemize}
    \item \code{DMA_RESUME}
      \begin{itemize}
      \item Resume a given channel
      \end{itemize}
    \item \code{DMA_TERMINATE_ALL}
      \begin{itemize}
      \item Aborts all transfers on a given channel
      \end{itemize}
    \item \code{DMA_SLAVE_CONFIG}
      \begin{itemize}
      \item Configures a given channel with new parameters
      \end{itemize}
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{Capabilities}
  \begin{itemize}
  \item \code{device_slave_caps}
  \item Returns various pieces of information about the controller
    \begin{itemize}
    \item Can the transfer be paused? terminated?
    \item Which transfer widths are supported?
    \item Which slave directions are supported?
    \end{itemize}
  \item Used by generic layers to get an idea of what the device
    they're going to use is capable of (only ASoC so far)
  \end{itemize}
\end{frame}

\subsection{Recent Developments}

\begin{frame}
  \frametitle{Generic Capabilities (3.20)}
  \begin{itemize}
  \item Removal of \code{device_slave_caps}, and moved the logic in
    the framework
  \item Introduction of new variables in \code{struct dma_device}
    \begin{description}
    \item[*\_width] Bitmask of supported transfer width, both as
      source and destination
    \item[directions] Bitmask of the supported slave directions
      (memory to device, device to memory, device to device)
    \item[granularity] Granularity of the transfer residue your
      controller can provide: bursts, chunks or descriptors
    \end{description}
  \item Split of the \code{device_control} function in four
    independent functions: \code{device_config}, \code{device_pause},
    \code{device_resume}, \code{device_terminate_all}
  \end{itemize}
\end{frame}

\begin{frame}
  \frametitle{Scheduled DMA}
  \begin{itemize}
  \item Many DMA controllers have more requests than channels
  \item These drivers usually have all the scheduling code
  \item Plus, every driver has a lot of administrative code, that is
    not trivial to get right (callback deferral, allocation of the
    descriptors, etc.), yet similar from one driver to another
  \item Scheduled DMA framework abstracts away most of it, and only a
    few things remain in the drivers:
    \begin{itemize}
    \item Interrupt management
    \item LLI related functions (iterators, configuration, etc.)
    \item Scheduling hints
    \item Channel management (pause, resume, residues, etc.)
    \end{itemize}
  \end{itemize}
\end{frame}

\questionslide{}

\end{document}
