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

\mode<presentation>
\usetheme{Bootlin}

\newcommand{\codecomment}[1]{{\color{red} \textit{#1}}}

\title{Common clock framework: how to use it}
\authors{Gregory CLEMENT}
\institute{Bootlin}

\usepackage{hyperref}

\begin{document}

\begin{frame}{Embedded Linux Conference 2013}
  \begin{columns}[c]
   \column{0.7\textwidth}
     \huge
     Common clock framework: how to use it\\
     \vspace{1cm}
     \normalsize
     Gregory CLEMENT\\
     {\bf Bootlin}\\
     {\em gregory.clement@bootlin.com}
     \column{0.3\textwidth}
     \includegraphics[width=\textwidth]{clock.png}
   \end{columns}
\end{frame}

\begin{frame}{Gregory CLEMENT}
  \begin{itemize}
  \item Embedded Linux engineer and trainer at Bootlin since
    2010
    \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 Contributing the {\bf kernel support for the new Armada 370
      and Armada XP} ARM SoCs from Marvell.
  \item Co-maintainer of mvebu sub-architecture (SoCs from Marvell
    Embedded Business Unit)
  \item Living near {\bf Lyon}, France
  \end{itemize}
\end{frame}

\begin{frame}{Overview}
  \begin{itemize}
  \item What the common clock framework is
  \item Implementation of the common clock framework
  \item How to add your own clocks
  \item How to deal with the device tree
  \item Use of the clocks by device drivers
  \end{itemize}
\end{frame}

\begin{frame}{Clocks}
  \begin{itemize}
  \item Most of the electronic chips are driven by {\bf clocks}
  \item The clocks of the peripherals of an {\bf SoC} (or even a {\bf
      board}) are organized in a {\bf tree}
  \item Controlling clocks is useful for:
    \begin{itemize}
    \item {\bf power management}: clock frequency is a parameter of
      the dynamic power consumption
    \item {\bf time reference}: to compute a baud-rate or a pixel
      clock for example
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{The clock framework}
  \begin{itemize}
  \item A {\bf clock framework} has been available for many years (it
    comes from the prehistory of git)
  \item Offers a a simple API: \code{clk_get}, \code{clk_enable},
    \code {clk_get_rate}, \code {clk_set_rate}, \code{clk_disable},
    \code{clk_put},\code{...} that were used by device drivers.
  \item Nice but had several drawbacks and limitations:
    \begin{itemize}
    \item Each machine class had its {\bf own implementation} of this
      API.
    \item Does not allow {\bf code sharing}, and common mechanisms
    \item Does not work for ARM {\bf multiplatform} kernels.
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{The common clock framework}
  \begin{itemize}
  \item Started by the introduction of a {\bf common struct clk} in
    early 2010 by {\bf Jeremy Kerr}
  \item Ended by the merge of the {\bf common clock framework} in
    kernel 3.4 in May 2012, submitted by {\bf Mike Turquette}
  \item Implements the {\bf clock framework API}, {\bf some basic
      clock drivers} and makes it possible to implement {\bf custom
      clock drivers}
  \item Allows to declare the available clocks and their association
    to devices in the Device Tree (preferred) or statically in the
    source code (old method)
  \item Provides a {\em debugfs} representation of the clock tree
  \item Is implemented in \path{drivers/clk}
  \end{itemize}
\end{frame}

\begin{frame}{Diagram overview of the common clock framework}
  \begin{center}
\includegraphics[width=\textwidth]{clock-framework.pdf}
\end{center}
\end{frame}

\begin{frame}{Interface of the CCF}
  Interface divided into two halves:
  \begin{itemize}
  \item Common Clock Framework core
    \begin{itemize}
    \item Common definition of struct clk
      % which unifies the framework-level accounting and
      % infrastructure that has traditionally been duplicated across a
      % variety of platforms.
    \item Common implementation of the \code{clk.h} API (defined in
      \path{drivers/clk/clk.c})
    \item \code{struct clk_ops}: operations invoked by the clk API
      implementation
    \item Not supposed to be modified when adding a new driver
    \end{itemize}
  \item Hardware-specific
    \begin{itemize}
    \item Callbacks registered with \code{struct clk_ops} and the
      corresponding hardware-specific structures (let's call it
      \code{struct clk_foo} for this talk)
    \item Has to be written for each new hardware clock
    \end{itemize}
  \item The two halves are tied together by \code{struct clk_hw},
    which is defined in \code{struct clk_foo} and pointed to within
    \code{struct clk}.
  \end{itemize}
\end{frame}

\begin{frame}{Implementation of the CCF core}
  \begin{center}
\includegraphics[width=\textwidth]{clock-framework-core.pdf}
\end{center}
\end{frame}

\begin{frame}{Implementation of the CCF core}
  Implementation defined in \code{drivers/clk/clk.c}. Takes care of:
  \begin{itemize}
    \item \textbf{Maintaining} the clock tree
    \item \textbf{Concurrency prevention} (using a global spinlock for
      \code{clk_enable()}/\code{clk_disable()} and a global mutex for
      all other operations)
    \item \textbf{Propagating} the operations through the clock tree
    \item \textbf{Notification} when rate change occurs on a given
      clock, the register callback is called.
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Implementation of the CCF core}
  Common \code{struct clk} definition located in
  \code{include/linux/clk-private.h}:
  \begin{minted}{c}
struct clk {
        const char             *name;
        const struct clk_ops   *ops;
        struct clk_hw          *hw;
        char                   **parent_names;
        struct clk             **parents;
        struct clk             *parent;
        struct hlist_head      children;
        struct hlist_node      child_node;
...
};
  \end{minted}
\end{frame}


\begin{frame}[fragile]{Implementation of the CCF core}
  The \code{clk_set_rate()} example:
  \footnotesize
  \begin{minted}{c}
int clk_set_rate(struct clk *clk, unsigned long rate)
{
        struct clk *top, *fail_clk;
        int ret = 0;
        /* prevent racing with updates to the clock topology */
        mutex_lock(&prepare_lock);
        /* bail early if nothing to do */
        if (rate == clk->rate)
                goto out;
        if ((clk->flags & CLK_SET_RATE_GATE) && clk->prepare_count) {
  \end{minted}
  \codecomment{For this particular clock, setting its rate is possible
    only if the clock is ungated (not yet prepared)}
  \begin{minted}{c}
                ret = -EBUSY;
                goto out;
        }
        /* calculate new rates and get the topmost changed clock */
        top = clk_calc_new_rates(clk, rate);
  \end{minted}
[...] \codecomment{Exit with error if \path{clk_calc_new_rates()} failed}
% calculate the new rates returning the topmost clock that has to be
% changed.
\end{frame}

\begin{frame}[fragile]{Implementation of the CCF core}
  The \code{clk_set_rate()} example (continued):
\footnotesize
  \begin{minted}{c}
        /* notify that we are about to change rates */
        fail_clk = clk_propagate_rate_change(top, PRE_RATE_CHANGE);
        if (fail_clk) {
                pr_warn("%s: failed to set %s rate\n", __func__,
                                fail_clk->name);
                clk_propagate_rate_change(top, ABORT_RATE_CHANGE);
                ret = -EBUSY;
                goto out;
        }
        /* change the rates */
        clk_change_rate(top);
  \end{minted}
\codecomment{Actually set the rate using the hardware operation}
  \begin{minted}{c}
out:
        mutex_unlock(&prepare_lock);
        return ret;
}
  \end{minted}
\end{frame}

\begin{frame}{Implementation of the hardware clock}
  \begin{center}
\includegraphics[width=\textwidth]{clock-framework-hw.pdf}
\end{center}
\end{frame}

\begin{frame}{Implementation of the hardware clock}
  \begin{itemize}
  \item Relies on \code{.ops} and \code{.hw} pointers
  \item Abstracts the details of \code{struct clk} from the
    hardware-specific bits
  \item No need to implement all the operations, only a \textbf{few
      are mandatory} depending on the clock type
  \item The clock is created once the operation set is registered using
    \code{clk_register()}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Implementation of the hardware clock}
  Hardware operations defined in \code{include/linux/clk-provider.h}
  \footnotesize
  \begin{minted}{c}
struct clk_ops {
        int             (*prepare)(struct clk_hw *hw);
        void            (*unprepare)(struct clk_hw *hw);
        int             (*enable)(struct clk_hw *hw);
        void            (*disable)(struct clk_hw *hw);
        int             (*is_enabled)(struct clk_hw *hw);
        unsigned long   (*recalc_rate)(struct clk_hw *hw,
                                       unsigned long parent_rate);
        long            (*round_rate)(struct clk_hw *hw, unsigned long,
                                       unsigned long *);
        int             (*set_parent)(struct clk_hw *hw, u8 index);
        u8              (*get_parent)(struct clk_hw *hw);
        int             (*set_rate)(struct clk_hw *hw, unsigned long);
        void            (*init)(struct clk_hw *hw);
};
  \end{minted}
\end{frame}

\newcommand\mandatory{{\color{Green} \textbf{y}}}
\newcommand\invalid{{\color{red} \textbf{n}}}

\begin{frame}{Operations to implement depending on clk capabilities}
  \begin{table}
    {\setlength{\arrayrulewidth}{1pt}
      \begin{tabular}{|l|c|c|c|c|c|}
      \hline
      & gate & change rate & single parent & multiplexer & root \\
      \hline
    .prepare &&&&&\\
    .unprepare &&&&&\\
    \hline
    .enable&\mandatory{}&&&&\\
    .disable&\mandatory{}&&&&\\
    .is\_enabled&\mandatory{} &&&&\\
    \hline
    .recalc\_rate&&\mandatory{}&&&\\
    .round\_rate&&\mandatory{}&&&\\
    .set\_rate&&\mandatory{}&&&\\
    \hline
    .set\_parent&&&\invalid{}&\mandatory{}&\invalid{}\\
    .get\_parent&&&\invalid{}&\mandatory{}&\invalid{}\\
    \hline
    .init &&&&&\\
    \hline
  \end{tabular}}
\renewcommand{\tablename}{Legend}
\caption {\mandatory{} = mandatory, \invalid{} = invalid or otherwise unnecessary}
\end{table}
\end{frame}

\begin{frame}{Hardware clock operations: making clocks available}
  The API is split in two pairs:
  \begin{itemize}
  \item \code{.prepare}(/\code{.unprepare}):
    \begin{itemize}
    \item Called to \textbf{prepare} the clock \textbf{before}
      actually ungating it
    \item Could be called in place of enable in some cases (accessed
      over I2C) %example in drivers/clk/clk-wm831x.c
    \item {\bf May sleep}
    \item \textbf{Must not} be called in \textbf{atomic context}
    \end{itemize}
  \item \code{.enable}(/\code{.disable}):
    \begin{itemize}
    \item Called to \textbf{ungate} the clock once it has been prepared
    \item Could be called in place of prepare in some case (accessed
      over single register in an SoC)
    \item Must \textbf{not sleep}
    \item Can be called in \textbf{atomic context}
    \item \code{.is_enabled}: Instead of checking the enable count,
      \textbf{querying the hardware} to determine if the clock is
      enabled.
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Hardware clock operations: managing the rates}
  \begin{itemize}
  \item \code{.round_rate}: Returns the \textbf{closest rate} actually
    \textbf{supported} by the clock. Called by \code{clk_round_rate()}
    or by \code{clk_set_rate()} during propagation.
  \item \code{.set_rate}: \textbf{Changes the rate} of the
    clock. Called by \code{clk_set_rate()} or during propagation.
  \item \code{.recalc_rate}: \textbf{Recalculates the rate} of this
    clock, by querying hardware supported by the clock. Used
    internally to update the clock tree.
  \end{itemize}
\end{frame}

\begin{frame}{Hardware clock operations: managing the parents}
  As seen on the matrix, only used for multiplexers
  \begin{itemize}
  \item \code{.get_parent}:
    \begin{itemize}
    \item \textbf{Queries the hardware} to determine the parent of a
      clock.
    \item Currently only used when clocks are statically initialized.
    \item \code{clk_get_parent()} doesn't use it, simply returns the
      \code{clk->parent} internal struct
    \end{itemize}
  \item \code{.set_parent}:
    \begin{itemize}
    \item \textbf{Changes} the input \textbf{source} of this clock
    \item Receives a index on in either the \code{.parent_names} or
      \code{.parents} arrays
%.parents is created on the fly for next use
    \item \code{clk_set_parent()} translate \code{clk} in index
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Hardware clock operations: base clocks}
  \begin{itemize}
  \item The common clock framework provides \textbf{5 base clocks}:
    \begin{itemize}
    \item \textbf{fixed-rate}: Is always running and provide always
      the same rate
    \item \textbf{gate}: Have the same rate as its parent and can
      only be gated or ungated
    \item \textbf{mux}: Allow to select a parent among several ones, get
      the rate from the selected parent, and can't gate or ungate
    \item \textbf{fixed-factor}: Divide and multiply the parent rate
      by constants, can't gate or ungate
    \item \textbf{divider}: Divide the parent rate, the divider can
      be selected among an array provided at registration, can't gate or
      ungate
    \end{itemize}
  \item Most of the clocks can be registered using one of these base
    clocks.
  \item Complex hardware clocks have to be split in base clocks
    \begin{itemize}
    \item For example a gate clock with a fixed rate will be composed
      of a fixed rate clock as a parent of a gate clock.
    \item New clock type submitted recently: \code{clk-composite}. It
      will allow to aggregate the functionality of the basic clock
      types into one clock.  Still under review.
    \end{itemize}
  \end{itemize}
\end{frame}


\begin{frame}{Hardware clock operations: static initialization}
  \begin{itemize}
  \item Put in place to \textbf{ease migration} of the complex SoC to
    the common clock framework
    \begin{itemize}
    \item Platforms used to use hundreds clocks statically defined
    \item They had to include \code{include/linux/clk-private.h} and
      \code{__clk_init()} to reuse these definitions.
    \end{itemize}
  \item Still \textbf{possible} (\emph{but not recommended}) to do
    static initialization
    \begin{itemize}
    \item \textbf{Absolutely no new platform} should include
      \code{clk-private.h}
    \item Clocks \textbf{must} be initialized via a call to
      \code{clk_register()} using \code{clk_init_data} objects which get
      bundled with \code{clk_hw}
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Hardware clock operations: device tree}
  \begin{center}
\includegraphics[width=\textwidth]{clock-framework-dt.pdf}
\end{center}
\end{frame}

\begin{frame}{Hardware clock operations: device tree}
  \begin{itemize}
  \item The \textbf{device tree} is the \textbf{preferred way} to
    declare a clock and to get its resources, as for any other driver
    using DT we have to:
    \begin{itemize}
    \item \textbf{Parse} the device tree to \textbf{setup} the clock:
      resources but also properties are retrieved.
    \item Create an \textbf{array} of\code{struct of_device_id} to
      \textbf{match} the compatible clocks
    \item Associate data and setup functions to each node
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Declaration of clocks in DT: simple example (1)}
  From \path{arch/arm/boot/dts/ecx-common.dtsi}
  \footnotesize
  \begin{minted}{perl}
[...]
       osc: oscillator {
                #clock-cells = <0>;
                compatible = "fixed-clock";
                clock-frequency = <33333000>;
        };

        ddrpll: ddrpll {
                #clock-cells = <0>;
                compatible = "calxeda,hb-pll-clock";
                clocks = <&osc>;
                reg = <0x108>;
        };
[...]
  \end{minted}
\end{frame}

\begin{frame}[fragile]{Managing the device tree: simple example (1)}
  From \path{drivers/clk/clk-highbank.c}
  \scriptsize
  \begin{minted}{c}
static const __initconst struct of_device_id clk_match[] = {
        { .compatible = "fixed-clock", .data = of_fixed_clk_setup, },
[...]
};

void __init highbank_clocks_init(void)
{
        of_clk_init(clk_match);
}
  \end{minted}
  \normalsize
  From \path{drivers/clk/clk.c}
  \scriptsize
  \begin{minted}{c}
void __init of_clk_init(const struct of_device_id *matches)
{
        struct device_node *np;
        for_each_matching_node(np, matches) {
                const struct of_device_id *match = of_match_node(matches, np);
                of_clk_init_cb_t clk_init_cb = match->data;
                clk_init_cb(np);
        }
}
  \end{minted}
\end{frame}

\begin{frame}[fragile]{Managing the device tree: simple example (2)}
  From \path{drivers/clk/clk-fixed-rate.c}
  \footnotesize
  \begin{minted}{c}
void __init of_fixed_clk_setup(struct device_node *node)
{
        struct clk *clk;
        const char *clk_name = node->name;
        u32 rate;

        if (of_property_read_u32(node, "clock-frequency", &rate))
                return;

        of_property_read_string(node, "clock-output-names", &clk_name);

        clk = clk_register_fixed_rate(NULL, clk_name, NULL,
                                      CLK_IS_ROOT, rate);
        if (!IS_ERR(clk))
                of_clk_add_provider(node, of_clk_src_simple_get, clk);
}
  \end{minted}
\end{frame}

\begin{frame}[fragile]{Declaration of clocks in DT: advanced example (1)}
  From \path{arch/arm/boot/dts/armada-xp.dtsi}
  \footnotesize
  \begin{minted}{perl}
        [...]
        coreclk: mvebu-sar@d0018230 {
                compatible = "marvell,armada-xp-core-clock";
                reg = <0xd0018230 0x08>;
                #clock-cells = <1>;
        };

        cpuclk: clock-complex@d0018700 {
                #clock-cells = <1>;
                compatible = "marvell,armada-xp-cpu-clock";
                reg = <0xd0018700 0xA0>;
                clocks = <&coreclk 1>;
        };
        [...]
  \end{minted}
\end{frame}

\begin{frame}[fragile]{Managing the device tree: advanced example (1)}
  From \path{drivers/clk/mvebu/clk-core.c} (some parts removed)
  \scriptsize
  \begin{minted}{c}
static const struct core_clocks armada_370_core_clocks = {
        .get_tclk_freq = armada_370_get_tclk_freq,
        .num_ratios = ARRAY_SIZE(armada_370_xp_core_ratios),
};
static const __initdata struct of_device_id clk_core_match[] = {
[...]
        {
                .compatible = "marvell,armada-xp-core-clock",
                .data = &armada_xp_core_clocks,
        },
[...]
};
void __init mvebu_core_clk_init(void)
{
        struct device_node *np;

        for_each_matching_node(np, clk_core_match) {
                const struct of_device_id *match =
                        of_match_node(clk_core_match, np);
                mvebu_clk_core_setup(np, (struct core_clocks *)match->data);
        }
}
  \end{minted}
\end{frame}

\begin{frame}[fragile]{Managing the device tree: advanced example (2)}
  From \path{drivers/clk/mvebu/clk-core.c} (some parts removed)
  \footnotesize
  \begin{minted}{c}
static void __init mvebu_clk_core_setup(struct device_node *np,
				 struct core_clocks *coreclk)
{
      const char *tclk_name = "tclk";
      void __iomem *base;

      base = of_iomap(np, 0);
      /* Allocate struct for TCLK, cpu clk, and core ratio clocks */
      clk_data.clk_num = 2 + coreclk->num_ratios;
      clk_data.clks = kzalloc(clk_data.clk_num * sizeof(struct clk *),
                              GFP_KERNEL);
      /* Register TCLK */
      of_property_read_string_index(np, "clock-output-names", 0,
                                    &tclk_name);
      rate = coreclk->get_tclk_freq(base);
      clk_data.clks[0] = clk_register_fixed_rate(NULL, tclk_name, NULL,
                                                 CLK_IS_ROOT, rate);
[...]
}
  \end{minted}
\end{frame}

\begin{frame}{Hardware clock operations: device tree}
  \begin{itemize}
  \item \textbf{Expose} the clocks to other nodes of the device tree
    using \code{of_clk_add_provider()} which takes 3 parameters:
    \begin{itemize}
    \item \code{struct device_node *np}: \textbf{Device node} pointer
      \textbf{associated} to \textbf{clock provider}. This one is
      usually received by the setup function, when there is a match,
      with the array previously defined.
    \item
      \code{struct clk *(*clk_src_get)(struct of_phandle_args *args, void *data)}:
      Callback for\textbf{ decoding clock}. For the devices, called
      through \code{clk_get()} to return the clock associated to the
      node.
%  clk_get()->of_clk_get_by_name()->of_clk_get()->of_clk_get_from_provider->provider->get
    \item \code{ void *data}: context pointer for the callback,
      usually a \textbf{pointer to the clock(s)} to associate to the
      node.
    \end{itemize}
  \end{itemize}
\end{frame}


\begin{frame}[fragile]{Exposing the clocks on DT: Simple example}
  From \path{drivers/clk/clk.c}
  \footnotesize
  \begin{minted}{c}
struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
                                     void *data)
{
        return data;
}
  \end{minted}
  \normalsize
  From \path{drivers/clk/clk-fixed-rate.c}
  \footnotesize
  \begin{minted}{c}
void __init of_fixed_clk_setup(struct device_node *node)
{
        struct clk *clk;
[...]
        clk = clk_register_fixed_rate(NULL, clk_name, NULL,
                                      CLK_IS_ROOT, rate);
        if (!IS_ERR(clk))
                of_clk_add_provider(node, of_clk_src_simple_get, clk);
}
  \end{minted}
\end{frame}

\begin{frame}[fragile]{Exposing the clocks in DT: Advanced example (1)}
  From \path{include/linux/clk-provider.h}
  \footnotesize
  \begin{minted}{c}
struct clk_onecell_data {
        struct clk **clks;
        unsigned int clk_num;
};
  \end{minted}
  \normalsize
  From \path{drivers/clk/clk.c}
  \footnotesize
  \begin{minted}{c}
struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec,
                                      void *data)
{
        struct clk_onecell_data *clk_data = data;
        unsigned int idx = clkspec->args[0];
        if (idx >= clk_data->clk_num) {
                return ERR_PTR(-EINVAL);
        }
        return clk_data->clks[idx];
}
  \end{minted}
\end{frame}

\begin{frame}[fragile]{Exposing the clocks in DT: Advanced example (2)}
  From \path{drivers/clk/mvebu/clk-core.c} (some parts removed)
  \footnotesize
  \begin{minted}{c}
static struct clk_onecell_data clk_data;
static void __init mvebu_clk_core_setup(struct device_node *np,
				 struct core_clocks *coreclk)
{
    clk_data.clk_num = 2 + coreclk->num_ratios;
    clk_data.clks = kzalloc(clk_data.clk_num * sizeof(struct clk *),
                                GFP_KERNEL);
[...]
    for (n = 0; n < coreclk->num_ratios; n++) {
[...]
        clk_data.clks[2+n] = clk_register_fixed_factor(NULL, rclk_name,
                               cpuclk_name, 0, mult, div);
    };
[...]
    of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
}
  \end{minted}
\end{frame}

\begin{frame}{How device drivers use the CCF}
  \begin{center}
\includegraphics[width=\textwidth]{clock-framework-device.pdf}
\end{center}
\end{frame}


\begin{frame}{How device drivers use the CCF}
  \begin{itemize}
  \item Use \code{clk_get()} to \textbf{get the clock} of the device
  \item \textbf{Link} between \textbf{clock and device} done either by
    platform data (old method) or by \textbf{device tree} (preferred
    method)
  \item Managed version: \code{devm_get_clk()}
  \item \textbf{Activate} the clock by \code{clk_enable()} and/or
    \code{clk_prepare()} (depending of the context),
    \textbf{sufficient} for most drivers.
  \item Manipulate the clock using the clock API
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Devices referencing their clock in the Device Tree}
  From \path{arch/arm/boot/dts/armada-xp.dtsi}
\begin{minted}{perl}
ethernet@d0030000 {
        compatible = "marvell,armada-370-neta";
        reg = <0xd0030000 0x2500>;
        interrupts = <12>;
        clocks = <&gateclk 2>;
        status = "disabled";
};
\end{minted}
  From \path{arch/arm/boot/dts/highbank.dts}
\begin{minted}{perl}
watchdog@fff10620 {
        compatible = "arm,cortex-a9-twd-wdt";
        reg = <0xfff10620 0x20>;
        interrupts = <1 14 0xf01>;
        clocks = <&a9periphclk>;
};
\end{minted}
\end{frame}

\begin{frame}[fragile]{Example clock usage in a driver}
  From \path{drivers/net/ethernet/marvell/mvneta.c}
  \scriptsize
\begin{minted}{c}
static void mvneta_rx_time_coal_set(struct mvneta_port *pp,
				    struct mvneta_rx_queue *rxq, u32 value)
{
[...]
        clk_rate = clk_get_rate(pp->clk);
        val = (clk_rate / 1000000) * value;
        mvreg_write(pp, MVNETA_RXQ_TIME_COAL_REG(rxq->id), val);
}

static int mvneta_probe(struct platform_device *pdev)
{
[...]
        pp->clk = devm_clk_get(&pdev->dev, NULL);
        clk_prepare_enable(pp->clk);
[...]
}
static int mvneta_remove(struct platform_device *pdev)
{
[...]
        clk_disable_unprepare(pp->clk);
[...]
}
\end{minted}
\end{frame}

\begin{frame}{Conclusion}
  \begin{center}
    \begin{itemize}
    \item \textbf{Efficient} way to declare and use clocks: the amount
      of code to support new clocks is very reduced.
    \item Still\textbf{ quite recent}:
      \begin{itemize}
      \item Complex SoCs still need to finish their migration
      \end{itemize}
    \item Upcoming features:
      \begin{itemize}
      \item \textbf{DVFS} (Patch set from Mike Turquette adding new
        notifications and reentrancy)
      \item \textbf{Composite clock} (Patch set from Prashant Gaikwad)
      \item Improve \textbf{debugfs} output by adding \textbf{JSON}
        style (also from Prashant Gaikwad)
      \end{itemize}
    \end{itemize}
  \end{center}
\end{frame}

\begin{frame}
  \begin{center}
  \Huge
  Questions?\\
  \vspace{1.5cm}
  \huge
  Gregory CLEMENT\\
  \large
  \vspace{0.5cm}
  \code{gregory.clement@bootlin.com}
  \vspace{1.0cm}\\
  \normalsize
  Thanks to Thomas Petazzoni,(Bootlin, working with me on
  Marvell
  mainlining), Mike Turquette (Linaro, CCF maintainer)\\
  \vspace{0.5cm}
  Slides under CC-BY-SA 3.0\\
  \scriptsize
  \url{http://bootlin.com/pub/conferences/2013/elc/common-clock-framework-how-to-use-it/}
  \end{center}
\end{frame}

\end{document}
