The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/arm/ti/ti_prcm.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2010
    3  *      Ben Gray <ben.r.gray@gmail.com>.
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 3. All advertising materials mentioning features or use of this software
   15  *    must display the following acknowledgement:
   16  *      This product includes software developed by Ben Gray.
   17  * 4. The name of the company nor the name of the author may be used to
   18  *    endorse or promote products derived from this software without specific
   19  *    prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY BEN GRAY ``AS IS'' AND ANY EXPRESS OR
   22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   24  * IN NO EVENT SHALL BEN GRAY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   30  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 /**
   34  * Power, Reset and Clock Managment Module
   35  *
   36  * This is a very simple driver wrapper around the PRCM set of registers in
   37  * the OMAP3 chip. It allows you to turn on and off things like the functional
   38  * and interface clocks to the various on-chip modules.
   39  *
   40  */
   41 #include <sys/cdefs.h>
   42 __FBSDID("$FreeBSD: releng/10.0/sys/arm/ti/ti_prcm.c 239281 2012-08-15 06:31:32Z gonzo $");
   43 
   44 #include <sys/param.h>
   45 #include <sys/systm.h>
   46 #include <sys/kernel.h>
   47 #include <sys/module.h>
   48 #include <sys/bus.h>
   49 #include <sys/resource.h>
   50 #include <sys/rman.h>
   51 #include <sys/lock.h>
   52 #include <sys/mutex.h>
   53 
   54 #include <machine/bus.h>
   55 #include <machine/cpu.h>
   56 #include <machine/cpufunc.h>
   57 #include <machine/frame.h>
   58 #include <machine/resource.h>
   59 #include <machine/intr.h>
   60 
   61 #include <arm/ti/ti_prcm.h>
   62 
   63 /**
   64  *      ti_clk_devmap - Array of clock devices, should be defined one per SoC 
   65  *
   66  *      This array is typically defined in one of the targeted *_prcm_clk.c
   67  *      files and is specific to the given SoC platform.  Each entry in the array
   68  *      corresponds to an individual clock device.
   69  */
   70 extern struct ti_clock_dev ti_clk_devmap[];
   71 
   72 /**
   73  *      ti_prcm_clk_dev - returns a pointer to the clock device with given id
   74  *      @clk: the ID of the clock device to get
   75  *
   76  *      Simply iterates through the clk_devmap global array and returns a pointer
   77  *      to the clock device if found. 
   78  *
   79  *      LOCKING:
   80  *      None
   81  *
   82  *      RETURNS:
   83  *      The pointer to the clock device on success, on failure NULL is returned.
   84  */
   85 static struct ti_clock_dev *
   86 ti_prcm_clk_dev(clk_ident_t clk)
   87 {
   88         struct ti_clock_dev *clk_dev;
   89         
   90         /* Find the clock within the devmap - it's a bit inefficent having a for 
   91          * loop for this, but this function should only called when a driver is 
   92          * being activated so IMHO not a big issue.
   93          */
   94         clk_dev = &(ti_clk_devmap[0]);
   95         while (clk_dev->id != INVALID_CLK_IDENT) {
   96                 if (clk_dev->id == clk) {
   97                         return (clk_dev);
   98                 }
   99                 clk_dev++;
  100         }
  101 
  102         /* Sanity check we managed to find the clock */
  103         printf("ti_prcm: Failed to find clock device (%d)\n", clk);
  104         return (NULL);
  105 }
  106 
  107 /**
  108  *      ti_prcm_clk_valid - enables a clock for a particular module
  109  *      @clk: identifier for the module to enable, see ti_prcm.h for a list
  110  *            of possible modules.
  111  *               Example: OMAP3_MODULE_MMC1_ICLK or OMAP3_MODULE_GPTIMER10_FCLK.
  112  *      
  113  *      This function can enable either a functional or interface clock.
  114  *
  115  *      The real work done to enable the clock is really done in the callback
  116  *      function associated with the clock, this function is simply a wrapper
  117  *      around that.
  118  *
  119  *      LOCKING:
  120  *      Internally locks the driver context.
  121  *
  122  *      RETURNS:
  123  *      Returns 0 on success or positive error code on failure.
  124  */
  125 int
  126 ti_prcm_clk_valid(clk_ident_t clk)
  127 {
  128         int ret = 0;
  129 
  130         if (ti_prcm_clk_dev(clk) == NULL)
  131                 ret = EINVAL;
  132         
  133         return (ret);
  134 }
  135 
  136 
  137 /**
  138  *      ti_prcm_clk_enable - enables a clock for a particular module
  139  *      @clk: identifier for the module to enable, see ti_prcm.h for a list
  140  *            of possible modules.
  141  *               Example: OMAP3_MODULE_MMC1_ICLK or OMAP3_MODULE_GPTIMER10_FCLK.
  142  *      
  143  *      This function can enable either a functional or interface clock.
  144  *
  145  *      The real work done to enable the clock is really done in the callback
  146  *      function associated with the clock, this function is simply a wrapper
  147  *      around that.
  148  *
  149  *      LOCKING:
  150  *      Internally locks the driver context.
  151  *
  152  *      RETURNS:
  153  *      Returns 0 on success or positive error code on failure.
  154  */
  155 int
  156 ti_prcm_clk_enable(clk_ident_t clk)
  157 {
  158         struct ti_clock_dev *clk_dev;
  159         int ret;
  160 
  161         /* Find the clock within the devmap - it's a bit inefficent having a for 
  162          * loop for this, but this function should only called when a driver is 
  163          * being activated so IMHO not a big issue.
  164          */
  165         clk_dev = ti_prcm_clk_dev(clk);
  166 
  167         /* Sanity check we managed to find the clock */
  168         if (clk_dev == NULL)
  169                 return (EINVAL);
  170 
  171         /* Activate the clock */
  172         if (clk_dev->clk_activate)
  173                 ret = clk_dev->clk_activate(clk_dev);
  174         else
  175                 ret = EINVAL;
  176 
  177         return (ret);
  178 }
  179 
  180 
  181 /**
  182  *      ti_prcm_clk_disable - disables a clock for a particular module
  183  *      @clk: identifier for the module to enable, see ti_prcm.h for a list
  184  *            of possible modules.
  185  *               Example: OMAP3_MODULE_MMC1_ICLK or OMAP3_MODULE_GPTIMER10_FCLK.
  186  *      
  187  *      This function can enable either a functional or interface clock.
  188  *
  189  *      The real work done to enable the clock is really done in the callback
  190  *      function associated with the clock, this function is simply a wrapper
  191  *      around that.
  192  *
  193  *      LOCKING:
  194  *      Internally locks the driver context.
  195  *
  196  *      RETURNS:
  197  *      Returns 0 on success or positive error code on failure.
  198  */
  199 int
  200 ti_prcm_clk_disable(clk_ident_t clk)
  201 {
  202         struct ti_clock_dev *clk_dev;
  203         int ret;
  204 
  205         /* Find the clock within the devmap - it's a bit inefficent having a for 
  206          * loop for this, but this function should only called when a driver is 
  207          * being activated so IMHO not a big issue.
  208          */
  209         clk_dev = ti_prcm_clk_dev(clk);
  210 
  211         /* Sanity check we managed to find the clock */
  212         if (clk_dev == NULL)
  213                 return (EINVAL);
  214 
  215         /* Activate the clock */
  216         if (clk_dev->clk_deactivate)
  217                 ret = clk_dev->clk_deactivate(clk_dev);
  218         else
  219                 ret = EINVAL;
  220         
  221         return (ret);
  222 }
  223 
  224 /**
  225  *      ti_prcm_clk_set_source - sets the source 
  226  *      @clk: identifier for the module to enable, see ti_prcm.h for a list
  227  *            of possible modules.
  228  *               Example: OMAP3_MODULE_MMC1_ICLK or OMAP3_MODULE_GPTIMER10_FCLK.
  229  *      
  230  *      This function can enable either a functional or interface clock.
  231  *
  232  *      The real work done to enable the clock is really done in the callback
  233  *      function associated with the clock, this function is simply a wrapper
  234  *      around that.
  235  *
  236  *      LOCKING:
  237  *      Internally locks the driver context.
  238  *
  239  *      RETURNS:
  240  *      Returns 0 on success or positive error code on failure.
  241  */
  242 int
  243 ti_prcm_clk_set_source(clk_ident_t clk, clk_src_t clksrc)
  244 {
  245         struct ti_clock_dev *clk_dev;
  246         int ret;
  247 
  248         /* Find the clock within the devmap - it's a bit inefficent having a for 
  249          * loop for this, but this function should only called when a driver is 
  250          * being activated so IMHO not a big issue.
  251          */
  252         clk_dev = ti_prcm_clk_dev(clk);
  253 
  254         /* Sanity check we managed to find the clock */
  255         if (clk_dev == NULL)
  256                 return (EINVAL);
  257 
  258         /* Activate the clock */
  259         if (clk_dev->clk_set_source)
  260                 ret = clk_dev->clk_set_source(clk_dev, clksrc);
  261         else
  262                 ret = EINVAL;
  263 
  264         return (ret);
  265 }
  266 
  267 
  268 /**
  269  *      ti_prcm_clk_get_source_freq - gets the source clock frequency
  270  *      @clk: identifier for the module to enable, see ti_prcm.h for a list
  271  *            of possible modules.
  272  *      @freq: pointer to an integer that upon return will contain the src freq
  273  *      
  274  *      This function returns the frequency of the source clock.
  275  *
  276  *      The real work done to enable the clock is really done in the callback
  277  *      function associated with the clock, this function is simply a wrapper
  278  *      around that.
  279  *
  280  *      LOCKING:
  281  *      Internally locks the driver context.
  282  *
  283  *      RETURNS:
  284  *      Returns 0 on success or positive error code on failure.
  285  */
  286 int
  287 ti_prcm_clk_get_source_freq(clk_ident_t clk, unsigned int *freq)
  288 {
  289         struct ti_clock_dev *clk_dev;
  290         int ret;
  291 
  292         /* Find the clock within the devmap - it's a bit inefficent having a for 
  293          * loop for this, but this function should only called when a driver is 
  294          * being activated so IMHO not a big issue.
  295          */
  296         clk_dev = ti_prcm_clk_dev(clk);
  297 
  298         /* Sanity check we managed to find the clock */
  299         if (clk_dev == NULL)
  300                 return (EINVAL);
  301 
  302         /* Get the source frequency of the clock */
  303         if (clk_dev->clk_get_source_freq)
  304                 ret = clk_dev->clk_get_source_freq(clk_dev, freq);
  305         else
  306                 ret = EINVAL;
  307         
  308         return (ret);
  309 }

Cache object: 51464536640e2979c3c432c08d0c13bc


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.