\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{Drive your NAND within Linux}
\conference{Embedded Linux Conference, March 12th 2018}
\authors{Miquèl Raynal}
\email{miquel@bootlin.com}
\institute{Bootlin}
\slidesurl{https://bootlin.com/pub/conferences/2018/fosdem/raynal-exec-op/}

\begin{document}

\addtocontents{toc}{\protect\setcounter{tocdepth}{-1}}
\section{Understand your NAND and drive it within Linux}
\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 Active contributor to 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}{What is this talk about?}
  \begin{itemize}
  \item Introduction to the basics of NAND flash memory
  \item How they are driven by the NAND controller
  \item Overview of the Linux memory stack, especially the new
    interface to drive NAND controllers: \code{->exec_op()}
  \end{itemize}
\end{frame}

\begin{frame}{Disclaimer}
  \begin{itemize}
  \item I am not a NAND expert, more the NAND maintainer slave
  \item I will probably oversimplify some aspects
  \item This presentation is not about history nor NOR technology
  \item Focus on SLC NAND (Single Level Cell) to simplify explanations,
    logic is similar with MLC/TLC NAND (Multi/Triple Level Cell)
  \end{itemize}
\end{frame}

\begin{frame}{The commercial minute}
  \begin{itemize}
  \item Main purpose: replace hard disks drives
  \item Main goal: lowest cost per bit
  \item Widely used in many consumer devices, embedded systems...
  \item Flavors:
    \begin{itemize}
    \item {\bf Raw NAND / parallel NAND \hspace{1cm}
      {\huge\color{red}$\Leftarrow$}}
    \item Serial NAND (mostly over SPI)
    \item Managed NAND with FTL (Flash Translation Layer)
      \begin{itemize}
      \item SD cards
      \item USB sticks
      \item SSD
      \item etc
      \end{itemize}
    \end{itemize}
  \end{itemize}
\end{frame}

% Have a look to Arnout Vandecappelle's talk in Berlin
\section{Understanding the NAND memory cell}

% Semiconductor (Silicon, Si), electrically balanced (neutral) Each atom
% of Silicon is surrounded by 14 electrons, categorized in 3 orbits
% (2/10/4). Each orbit correspond to an energy level (quanta) and an
% electron can make it to move to another layer it is more
% exited. Valence Electrons, those in the last orbit (called the valence
% shell), the farthest from the nucleus, have much more energy and thus
% are quite unstable as the valence band is not full of electrons (2 x
% 4^2). They will bond easily with other Silicon atoms, making crystals
% of Silicon, the matter we will use to make transistors.
\begin{frame}{Back to school: Silicon}
  \begin{itemize}
  \item Silicon, Si
    \begin{itemize}
    \item Electrically balanced (neutral)
    \item 14 electrons spread in 3 orbits
    \item 4 electrons in the valence shell \textrightarrow{} easy
      bonding with other Silicon atoms (crystal)
    \end{itemize}
  \end{itemize}
  \begin{center}
    \includegraphics[scale=0.1]{cell-silicon.pdf}
  \end{center}
\end{frame}

% Electricity is a matter of having free electrons. In crystal Silicon,
% all valence electrons are bound to another valence electron from a
% neighbor Si atom, so the matter is electrically stable and the Si
% almost an insulator -> it would be at absolute 0 (-273.15°C).
%
% When light stokes an electron in the valence band, if it absorbs
% enough energy it will jump to the conduction band, as a free electron,
% creating a hole, until it looses its energy and falls back into the
% valence band (recombination).
%
% At any moment, free electrons drift randomly unless a voltage across
% the semiconductor is applied, and these free electrons will be
% attracted to the positive end
\begin{frame}{Back to school: electricity}
  \begin{itemize}
  \item Electricity $\implies{}$ free electrons
    \begin{itemize}
    \item Silicon is almost an insulator
    \item Valence electron stroke by light \textrightarrow{} absorbs
      energy \textrightarrow{} jumps to the conduction band
    \item Free electrons drift randomly unless a voltage is applied
      \textrightarrow{} attracted to the + side
    \end{itemize}
  \end{itemize}
  \begin{center}
    \includegraphics[scale=0.09]{cell-silicon-stroke.pdf}
  \end{center}
\end{frame}

% To enhance the conductivity, impurity atoms are added in intrinsic
% semiconductor: it is called doping. If you replace an Si atom with
% another atom that has 5 valence electrons, it means once it will be
% bound to 4 Si atoms, there will be one free electron. This is N
% doping, because you add electrons. The opposite is also used, using an
% atom with only 3 valence electrons, one of the neighbors will miss a
% covalent bond, this is called a hole and this is P doping. While there
% are free electrons in there, the matter is still electrically neutral
% because there are as much electrons as protons in both types.
\begin{frame}{Back to school: doping}
  \begin{itemize}
  \item Nothing to do with cycling
  \item Purpose of doping: enhance conductivity
    \begin{itemize}
    \item Add impurities (atoms with more or less valence electrons than Si)
    \item Once bound with 4 Si atoms:
      \begin{itemize}
      \item 1 free electron \textleftarrow{} N-doping
      \item 1 hole \textleftarrow{} P-doping
      \end{itemize}
    \item Still electrically neutral
    \end{itemize}
  \end{itemize}
\end{frame}

% Join a n-type and a p-type. p lacks electrons, while n has too much,
% electrons will cross the PN region to combine with a hole close to the
% junction, giving up their energy. The N region close to the junction
% will lack electrons and became electrically positive, while the P
% region close to the junction will lack holes and become negative. This
% will make a barrier potential hard to cross for other
% electrons. Because valence band and conduction band energy levels are
% higher with P than N doping, only very high energy free electrons from
% the N substrate will be able to cross the junction, loosing their
% energy and combining with a hole. After some time, no more electrons
% from the N substrate will have enough energy to cross the barrier
% without more energy.
%
% Apply a forward bias, electrons in the junction area are attracted to
% the + side and will jump from hole to hole until it gets out of the
% circuit, letting other electrons from the N side jump to a freshly
% freed hole. e- can cross the depletion region, it creates a current.
%
% Apply a reverse bias: the minus regions on the p material attract
% holes, widening the depletion region without holes, in the opposite,
% free electrons are attracted towards the + side, also widening the
% depletion region, making it difficult to be crossed: no more
% current.
\begin{frame}{P-N junction: the diode}
  \begin{itemize}
  \item Electrons close to the junction will jump to recombine with
    the closest hole
  \item Creation of a barrier of potential: a non-crossable electric
    field
  \item Depletion region thickness is modular
  \end{itemize}
  \begin{overprint}
    \onslide<1>\centerline{\includegraphics[scale=0.12]{cell-diode.pdf}}
    \onslide<2>\centerline{\includegraphics[scale=0.12]{cell-diode-bias.pdf}}
  \end{overprint}
\end{frame}

% P substrate, with two highly doped N regions. Apply a voltage across
% both N regions: no current will flow. Add a metal-oxide region in the
% middle and apply a + voltage on it. It will create an electrical field
% that will attract electrons on the P top layer, and repels holes,
% creating a channel that can carry electrons through the P junctions
% from the source to the drain.
\begin{frame}{Metal-Oxide-Semiconductor Field-Effect Transistor}
  \begin{overprint}
      \onslide<1>\centerline{\includegraphics[scale=0.12]{cell-mosfet.pdf}}
      \onslide<2>\centerline{\includegraphics[scale=0.12]{cell-mosfet-blocking.pdf}}
      \onslide<3>\centerline{\includegraphics[scale=0.12]{cell-mosfet-passing.pdf}}
  \end{overprint}
\end{frame}

% Let's add an extra gate (known as the floating gate), isolated from
% both the p substrate and the control gate: charges inside the floating
% gate should remain there. That is what allows a floating gate
% transistor to store data.
%
% The common way to encode a bit of data (in SLC, Single Level Cell) is
% to put either negative charges, or no charge at all in the floating
% gate. When there are negative charges in the floating gate, the
% transistor acts like an open switch (current does not flow
% through it), which is a zero. Otherwise when there is no charge, the
% current simply pass through the transistor, it's like an closed
% switch: a one.
\begin{frame}{Floating-gate transistor}
  \begin{center}
    \includegraphics[scale=0.12]{cell-fg.pdf}
  \end{center}
\end{frame}

\begin{frame}{Floating-gate transistor: reading a one}
  \begin{center}
    \includegraphics[scale=0.12]{cell-fg-passing.pdf}
  \end{center}
\end{frame}

\begin{frame}{Floating-gate transistor: reading a zero}
  \begin{center}
    \includegraphics[scale=0.12]{cell-fg-blocking.pdf}
  \end{center}
\end{frame}

% There is no electrical contact to the floating gate. Instead, quantum
% tunneling is used to move charges through the oxide layer.
%
% The energy needed by an electron to jump over a barrier (in our case,
% the oxide layer), is proportional to the exponential of the thickness
% of that barrier. It means that electrons passing through the P
% substrate could actually jump over the barrier if it is narrow, and
% stay out of it if it is wide. The way we could act on that barrier is
% by applying an electric field that will attract electrons through
% it. But unlike when applying a voltage to read, we will have to apply
% a much higher voltage to allow the electrons to pass through the oxide
% layer.
%
% The opposite works also: apply a high negative voltage on the control
% gate, electrons in the floating gate will be pushed back into the
% channel, thus, erasing the bit back to 1.
\begin{frame}{Programming a cell to a 0 state}
  \begin{itemize}
  \item Change the charge of the floating-gate
  \item No electrical contact \textrightarrow{} Fowler-Nordheim
    tunneling
  \end{itemize}
  \begin{center}
    \includegraphics[scale=0.1]{cell-fg-tunnel-program.pdf}
  \end{center}
\end{frame}

\begin{frame}{Erasing a cell to a 1 state}
  \begin{itemize}
  \item Reverse the electric field
  \item Done by applying a high negative voltage on the control gate
  \end{itemize}
  \begin{center}
    \includegraphics[scale=0.1]{cell-fg-tunnel-erase.pdf}
  \end{center}
\end{frame}

% And here we have our memory cell: one bit of data
\begin{frame}{Memory cell}
  \begin{center}
    \includegraphics[scale=0.1]{memory-cell.pdf}
  \end{center}
\end{frame}

\begin{frame}{NAND gate}
  \begin{overprint}
    \onslide<1>\centerline{\includegraphics[scale=0.1]{memory-cell-serial.pdf}}
    \onslide<2>\centerline{\includegraphics[scale=0.1]{memory-cell-serial-n.pdf}}
    \onslide<3>\centerline{\includegraphics[scale=0.097]{memory-cell-serial-nand.pdf}}
  \end{overprint}
\end{frame}

% Drain and sources are connected together (there is actually only one N
% substratum acting for two transistors (the bit line). Cells are in
% series, and the number of cells on one bit line can be extended
% without scaling problem on the sensing area on top of it (to measure
% current). The only problem is the resistivity of individual cells
% (0.7V each). Strings of 32/64 cells. Each string can give at any time
% the value of only one cell in it.
%
% The charges in the floating gate imply a current by they own but as
% cells are in series (strings) we need to make them all conductive but
% one in order to get a single bit.
% To make the transistor always passing, applying a higher voltage on
% the control gate is enough for a bit value of 0 (when there are a lot
% of negative charges in the floating gate). This charge is big enough
% to imply a current in the MOSFET, but not too strong to avoid
% tunneling effect.
\begin{frame}{Memory string}
  \begin{overprint}
    \onslide<1>\centerline{\includegraphics[scale=0.043]{memory-string.pdf}}
    \onslide<2>\centerline{\includegraphics[scale=0.043]{memory-string-read.pdf}}
  \end{overprint}
\end{frame}

% On the control gate there is a the ``word line''. The number of
% parallel strings is typically unlimited (tens of thousands) that form
% a page. So when you select the ``word line'', you actually select all
% the cells of an entire page, explaining why you can only read/write a
% page at a time.
\begin{frame}{Memory array}
  \begin{overprint}
    \onslide<1>\centerline{\includegraphics[scale=0.0205]{memory-array.pdf}}
    \onslide<2>\centerline{\includegraphics[scale=0.020]{memory-array-details.pdf}}
  \end{overprint}
\end{frame}

% Note on erasing: usually it is done by applying a negative voltage on
% the control gate but unfortunately it is not as easy to produce
% negative voltages so what has been done is to reverse the electric
% field by wiring the gate to the ground and applying a high voltage on
% the bulk. Problem is, the bulk is the same for all cells, thus erasing
% an entire block.
\begin{frame}{Erasing}
  \begin{itemize}
  \item High negative voltage \textrightarrow{} not that easy to produce
  \item Bulk is the same for all cells \textrightarrow{} ``eraseblock''
  \end{itemize}
  \begin{center}
    \includegraphics[scale=0.1]{cell-fg-tunnel-erase-real.pdf}
  \end{center}
\end{frame}

\begin{frame}{Special care}
  \begin{itemize}
  \item {\bf Always} erase before programming
    \begin{itemize}
    \item ``Clean'' erased state is only 1111... everywhere because
      floating gates are not electrically charged.
    \item Writing is a one-way operation that brings more electrons in
      the floating-gate.
      \item This is ``programming a 0''.
    \item There is no ``programming a 1'' action.
    \end{itemize}
  \end{itemize}
\end{frame}

% Tunneling -> stochastically distributed
\begin{frame}{Main design flaw: bitflips}
  \begin{columns}[c]
    \column{0.6\textwidth}
    \begin{itemize}

      \visible<1->{
      \item Cells may not be fully erased/programmed
        \begin{itemize}
        \item Electrons without enough energy might get trapped, creating
          a depletion region
        \item Oxide becomes negative, preventing tunneling of the
          electrons if the barrier gets too high
      \end{itemize}}

      \visible<2->{
      \item Data retention issue
        \begin{itemize}
        \item Writing/erasing moves electrons through the oxide layer
        \item Electrons will dissipate their energy colliding with the
          material, damaging it\\ \textrightarrow{} possible charge loss
        \end{itemize}
      }

      \visible<3->{
      \item Read/write disturbances
      \item $\sim$100k program/erase cycles with SLC NAND
      }
    \end{itemize}

    \column{0.34\textwidth}
    \begin{center}
      \begin{overprint}
        \onslide<1>\centerline{\includegraphics[scale=0.08]{bf-barrier.pdf}}
        \onslide<2>\centerline{\includegraphics[scale=0.08]{bf-retention.pdf}}
      \end{overprint}
    \end{center}
  \end{columns}
\end{frame}

\section{Driving a NAND chip: the NAND controller}

% The chip is the NAND controller's slave and respond to stimuli only
% There are other notations depending on the spec, but these are for
% ONFI SDR interface which is very common:
% * CE: Chip Enable: The chip is selected by the host and must be
% operational
% * RB: Ready/Busy: The NAND holds this line until its internal operation
% finishes and the chip is ready to process another input from the host
% * WP: Write Protect: Disable NAND program/erase operations
% * CLE: Command Latch Enable: The current stream on the bus must be
% interpreted by the NAND chip as a command cycle
% * ALE: Address Latch Enable: The current stream on the bus must be
% interpreted by the NAND chip as an address cycle
% * RE/WE: Read Enable/Write Enable: The current stream is input or
% output data
% * I/O: 8-bit or 16-bit half-duplex bus for command, address and data
% streams
\begin{frame}{NAND bus}
  \begin{center}
    \includegraphics[scale=0.5]{rawnand-interface.pdf}
  \end{center}
\end{frame}

% Focus on the IO lines: the protocol
% Took inspiration from Boris's talk on the NAND framework at ELC 2016
% What is an instruction
% What is an operation
% Do a specific operation (read page, write page, read an ID, change a
% parameter). Done with one or several command, address, data cycles.
\begin{frame}{NAND protocol}
  \begin{center}
    \includegraphics[scale=0.4]{nand-protocol.pdf}
  \end{center}
\end{frame}

\begin{frame}{NAND protocol (examples)}
  \begin{center}
    \includegraphics[scale=0.4]{nand-operations.pdf}
  \end{center}
\end{frame}

\begin{frame}{NAND controller}
  \begin{itemize}
  \item Controllers are often embedded in an SoC
  \item Diverse implementations, from the most simplest to highly
    sophisticated ones
  \item Controller job: communicate with the NAND chip
    \begin{itemize}
      \item Can embed an ECC engine to handle bitflips
      \item Can embed advanced logic to optimize throughput
        \begin{itemize}
        \item Sequential accesses
        \item Parallel die accesses
        \end{itemize}
    \end{itemize}
  \end{itemize}
\end{frame}

\section{Dealing with NAND from Linux}

\begin{frame}{Linux Memory Technology Device stack (MTD)}
  \begin{center}
    \includegraphics[scale=0.15]{nand-mtd-stack.pdf}
  \end{center}
\end{frame}

\begin{frame}{When there were still dinosaurs}
  \begin{center}
    \includegraphics[scale=0.4]{nand-proto-implem.pdf}
  \end{center}
\end{frame}

\begin{frame}{NAND legacy stack}
  \begin{center}
    \includegraphics[scale=0.19]{nand-legacy-stack.pdf}
  \end{center}
\end{frame}

% Took inspiration from Boris's talk on the NAND framework at ELC 2016
% This approach worked very well with simple NAND controllers, which are
% just able to send command and address cycles one at a time to the NAND
% chip, without any extra intelligence.
\begin{frame}{Limitations of the old methods}
  \begin{itemize}
  \item NAND controllers have become more complex
    \begin{itemize}
    \item Can handle higher-level operations
      \begin{itemize}
      \item higher performances?
      \end{itemize}
    \item May provide support for operations that would do all
      command/address/data cycles in one-go
    \item Some controllers are not able anymore to do basic operations
      (single cycles)
      \begin{itemize}
      \item They cannot send a single command, address or data cycle!
      \end{itemize}
    \end{itemize}
  \item Workaround: overload \code{->cmdfunc()}
  \end{itemize}
\end{frame}

\begin{frame}{Drawbacks of overloading \code{->cmdfunc()}}
  \begin{itemize}
  \item NAND controller drivers have to re-implement everything
    \begin{itemize}
    \item Encourages people to implement a minimal set of commands
    \end{itemize}
  \item Logic changes from driver to driver
    \begin{itemize}
    \item NAND operations evolve over the time \textrightarrow{} new
      vendor specific operations
      \begin{itemize}
        \item Hard to maintain as support across the NAND controllers is
          not uniform
        \item Need to patch all the drivers for additions supposedly
          simple in the core
      \end{itemize}
    \item According to the NAND maintainer, vendors are still creative
      \begin{quote}
        ``Why are they so mean to us?!'' -- Boris Brezillon, 04/01/2018
      \end{quote}
    \end{itemize}
  \item Some controllers need the length of the data transfer
    \begin{itemize}
    \item Not available in \code{->cmdfunc()}
    \item Drivers started predicting what the core ``next move'' would be
    \end{itemize}
  \item Clear symptoms that the framework was not fitting the user needs
    anymore
  \end{itemize}
\end{frame}

\begin{frame}{Addressing these limitations: {\bf\code{->exec_op()}}}
  \begin{itemize}
  \item New interface that asks to execute the whole operation
    % Including the IO and the wait states
  \item Just a translation in NAND operations of the MTD layer orders
    \begin{itemize}
    \item Doesn't try to be smart, logic should be in the NAND framework
    \end{itemize}
  \item Calls the controller \code{->exec_op()} hook and passes it an
    array of instructions to execute
  \item Should fit most NAND controllers we already know about
  \item Introduced in Linux v4.16
  \item Marvell's NAND controller driver migrated
  \item More to come: FSMC, Sunxi, VF610, Arasan, MXC, Atmel...
  \end{itemize}
\end{frame}

% People might think that this is a lot of logic added on the
% controller's side but in fact it is not. For very simple controllers,
% this parser is just a matter of going by all the instructions
% sequentially and translate them into register writes.
% Otherwise, use the core's parser!
\begin{frame}{{\bf\code{->exec_op()}} controller's implementation}
  \begin{itemize}
  \item When receiving an array of sequential instructions:
    \begin{itemize}
    \item Parses the sequence
      \begin{itemize}
      \item Splits in as much sub-operations as needed to perform the
        task
      \end{itemize}
    \item Declares if the overall operation can be handled
      \begin{itemize}
         % Today, ->cmdfunc() does not return an error code while when
         % an operation is not supported by the controller, we would
         % like to try with another way (most of the time there are
         % multiple ways to do it differetly) even if it is less
         % performant.
      \item Otherwise returns -ENOTSUPP
      \end{itemize}
      % Returning -ENOTSUPP is very important as it returns the information to
      % the NAND core that the operation did not succeed. It was not the case
      % with ->cmdfunc()/->cmd_ctrl().
    \end{itemize}
  \item Simple controllers \textrightarrow{} trivial logic
  \item More complex controllers \textrightarrow{} use the core's parser
  \end{itemize}
\end{frame}

% Some controllers are more complicated than that, and that is why we
% added a generic parser in the core. On his side, the controller should
% fill an array of supported patterns and give it to the parser.
% Each pattern shall have a callback supposed to execute the
% sub-operation handled by this pattern. The parser will then find the
% first match and execute that callback.
%
% Iterating on all the instructions until all gets executed
% Patterns shall be ordered in decreasing complexity order
\begin{frame}{Parser}
  \begin{center}
    \includegraphics[scale=0.2]{nand-stack.pdf}
  \end{center}
\end{frame}

% Patterns = constraints + callback
\begin{frame}{Patterns}
  \begin{center}
    \includegraphics[scale=0.28]{nand-patterns.pdf}
  \end{center}
\end{frame}

\begin{frame}{Swipe right to match}
  \begin{columns}[c]
    \column{0.5\textwidth}
    \begin{center}
      \includegraphics[scale=0.28]{nand-patterns-examples.pdf}
    \end{center}
    \column{0.5\textwidth}
    \begin{center}
      \includegraphics[scale=0.23]{nand-patterns.pdf}
    \end{center}
  \end{columns}
\end{frame}

\begin{frame}{NAND hooks}
  \begin{itemize}
  \item Various hooks should be implemented by the controller driver
    \begin{itemize}
    \item \code{->exec_op()} is one tool to do ``low-level'' operations
    \item \code{->setup_data_interface()} to manage controller timings
    \item \code{->select_chip()} to select a NAND chip die
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Good habits when you hack a NAND controller driver}
  \begin{itemize}
    \onslide<1->\item Test with the userspace tools through the
    \code{/dev/mtd*} devices\\
    mtd-utils: \code{nandbiterrs}, \code{nandreadpage},
    \code{flash_speed}, \code{flash_erase}, \code{nanddump},
    \code{nandwrite}, etc
    \onslide<2->\item Get the NAND documentation\\
    \code{dd if=/dev/zero of=nand.txt}
    \onslide<3->\item Ping the MTD community early on the public mailing-list
    \onslide<4->\item Do not forget to add the maintainer(s) in copy,
    it puts them in a bad mood
    \centerline{\includegraphics[scale=0.2]{boris.pdf}}
  \end{itemize}
\end{frame}

\begin{frame}{Sources/Links}
  \begin{itemize}
  \item Presentation by Boris Brezillon (Bootlin) at ELCE
    2016 in Berlin:
    ``Modernizing the NAND framework, the big picture''\\
    \url{https://www.youtube.com/watch?v=vhEb0fgk71M}\\
    \url{https://events.linuxfoundation.org/sites/events/files/slides/brezillon-nand-framework_0.pdf}
  \item Presentation by Arnout Vandecappelle (Essensium/Mind) at ELCE
    2016 in Berlin:
    ``Why NAND flash breaks down''\\
    \url{https://www.youtube.com/watch?v=VajB8vCsZ3s}\\
    \url{https://schd.ws/hosted_files/openiotelceurope2016/36/Flash-technology-ELCE16.pdf}
  \item YouTube channel ``Learn engineering'' that democratizes physical
    concepts\\
    \url{https://www.youtube.com/watch?v=7ukDKVHnac4}
  \item SlideShare by Nur Baya Binti Mohd Hashim (UNIMAP) about
    semiconductors\\
    \url{http://slideplayer.com/slide/10946788}
  \end{itemize}
\end{frame}

\begin{frame}
  \centering
  \Huge
  Questions? Suggestions? Comments?\\
  \vspace{0.5cm}
  \huge
  Miquèl Raynal\\
  \large
  \vspace{0.5cm}
  \hspace{2.6cm}\code{miquel@bootlin.com}
  \vspace{0.5cm}
  \newline Slides under CC-BY-SA 3.0\\
  \scriptsize
  \url{https://bootlin.com/pub/conferences/2018/fosdem/raynal-exec-op/}
    \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}

\begin{frame}{Backup}
  \begin{itemize}
  \item For throughput or compatibility purpose, a controller driver
    may overload the following functions defined by the core to bypass
    \code{->exec_op()} and talk directly to the NAND controller
    \begin{itemize}
    \item \code{->read/write_page()}
    \item \code{->read/write_oob()}
      \begin{itemize}
      \item Bitflips should be corrected and reported by the controller driver
      \item Let the NAND core handle the rest and report to upper layers
      \end{itemize}
    \end{itemize}
  \item It is also mandatory to fill their ``raw'' counterpart in
    order to be able to test and debug all the functionalities of the
    driver
    \begin{itemize}
    \item \code{->read/write_page_raw()}
    \item \code{->read/write_oob_raw()}
    \end{itemize}
  \end{itemize}
\end{frame}

\end{document}
