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.2/sys/arm/ti/ti_prcm.c 259329 2013-12-13 20:43:11Z ian $");
   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/resource.h>
   58 #include <machine/intr.h>
   59 
   60 #include <arm/ti/ti_prcm.h>
   61 
   62 /**
   63  *      ti_clk_devmap - Array of clock devices, should be defined one per SoC 
   64  *
   65  *      This array is typically defined in one of the targeted *_prcm_clk.c
   66  *      files and is specific to the given SoC platform.  Each entry in the array
   67  *      corresponds to an individual clock device.
   68  */
   69 extern struct ti_clock_dev ti_clk_devmap[];
   70 
   71 /**
   72  *      ti_prcm_clk_dev - returns a pointer to the clock device with given id
   73  *      @clk: the ID of the clock device to get
   74  *
   75  *      Simply iterates through the clk_devmap global array and returns a pointer
   76  *      to the clock device if found. 
   77  *
   78  *      LOCKING:
   79  *      None
   80  *
   81  *      RETURNS:
   82  *      The pointer to the clock device on success, on failure NULL is returned.
   83  */
   84 static struct ti_clock_dev *
   85 ti_prcm_clk_dev(clk_ident_t clk)
   86 {
   87         struct ti_clock_dev *clk_dev;
   88         
   89         /* Find the clock within the devmap - it's a bit inefficent having a for 
   90          * loop for this, but this function should only called when a driver is 
   91          * being activated so IMHO not a big issue.
   92          */
   93         clk_dev = &(ti_clk_devmap[0]);
   94         while (clk_dev->id != INVALID_CLK_IDENT) {
   95                 if (clk_dev->id == clk) {
   96                         return (clk_dev);
   97                 }
   98                 clk_dev++;
   99         }
  100 
  101         /* Sanity check we managed to find the clock */
  102         printf("ti_prcm: Failed to find clock device (%d)\n", clk);
  103         return (NULL);
  104 }
  105 
  106 /**
  107  *      ti_prcm_clk_valid - enables a clock for a particular module
  108  *      @clk: identifier for the module to enable, see ti_prcm.h for a list
  109  *            of possible modules.
  110  *               Example: OMAP3_MODULE_MMC1_ICLK or OMAP3_MODULE_GPTIMER10_FCLK.
  111  *      
  112  *      This function can enable either a functional or interface clock.
  113  *
  114  *      The real work done to enable the clock is really done in the callback
  115  *      function associated with the clock, this function is simply a wrapper
  116  *      around that.
  117  *
  118  *      LOCKING:
  119  *      Internally locks the driver context.
  120  *
  121  *      RETURNS:
  122  *      Returns 0 on success or positive error code on failure.
  123  */
  124 int
  125 ti_prcm_clk_valid(clk_ident_t clk)
  126 {
  127         int ret = 0;
  128 
  129         if (ti_prcm_clk_dev(clk) == NULL)
  130                 ret = EINVAL;
  131         
  132         return (ret);
  133 }
  134 
  135 
  136 /**
  137  *      ti_prcm_clk_enable - enables a clock for a particular module
  138  *      @clk: identifier for the module to enable, see ti_prcm.h for a list
  139  *            of possible modules.
  140  *               Example: OMAP3_MODULE_MMC1_ICLK or OMAP3_MODULE_GPTIMER10_FCLK.
  141  *      
  142  *      This function can enable either a functional or interface clock.
  143  *
  144  *      The real work done to enable the clock is really done in the callback
  145  *      function associated with the clock, this function is simply a wrapper
  146  *      around that.
  147  *
  148  *      LOCKING:
  149  *      Internally locks the driver context.
  150  *
  151  *      RETURNS:
  152  *      Returns 0 on success or positive error code on failure.
  153  */
  154 int
  155 ti_prcm_clk_enable(clk_ident_t clk)
  156 {
  157         struct ti_clock_dev *clk_dev;
  158         int ret;
  159 
  160         /* Find the clock within the devmap - it's a bit inefficent having a for 
  161          * loop for this, but this function should only called when a driver is 
  162          * being activated so IMHO not a big issue.
  163          */
  164         clk_dev = ti_prcm_clk_dev(clk);
  165 
  166         /* Sanity check we managed to find the clock */
  167         if (clk_dev == NULL)
  168                 return (EINVAL);
  169 
  170         /* Activate the clock */
  171         if (clk_dev->clk_activate)
  172                 ret = clk_dev->clk_activate(clk_dev);
  173         else
  174                 ret = EINVAL;
  175 
  176         return (ret);
  177 }
  178 
  179 
  180 /**
  181  *      ti_prcm_clk_disable - disables a clock for a particular module
  182  *      @clk: identifier for the module to enable, see ti_prcm.h for a list
  183  *            of possible modules.
  184  *               Example: OMAP3_MODULE_MMC1_ICLK or OMAP3_MODULE_GPTIMER10_FCLK.
  185  *      
  186  *      This function can enable either a functional or interface clock.
  187  *
  188  *      The real work done to enable the clock is really done in the callback
  189  *      function associated with the clock, this function is simply a wrapper
  190  *      around that.
  191  *
  192  *      LOCKING:
  193  *      Internally locks the driver context.
  194  *
  195  *      RETURNS:
  196  *      Returns 0 on success or positive error code on failure.
  197  */
  198 int
  199 ti_prcm_clk_disable(clk_ident_t clk)
  200 {
  201         struct ti_clock_dev *clk_dev;
  202         int ret;
  203 
  204         /* Find the clock within the devmap - it's a bit inefficent having a for 
  205          * loop for this, but this function should only called when a driver is 
  206          * being activated so IMHO not a big issue.
  207          */
  208         clk_dev = ti_prcm_clk_dev(clk);
  209 
  210         /* Sanity check we managed to find the clock */
  211         if (clk_dev == NULL)
  212                 return (EINVAL);
  213 
  214         /* Activate the clock */
  215         if (clk_dev->clk_deactivate)
  216                 ret = clk_dev->clk_deactivate(clk_dev);
  217         else
  218                 ret = EINVAL;
  219         
  220         return (ret);
  221 }
  222 
  223 /**
  224  *      ti_prcm_clk_set_source - sets the source 
  225  *      @clk: identifier for the module to enable, see ti_prcm.h for a list
  226  *            of possible modules.
  227  *               Example: OMAP3_MODULE_MMC1_ICLK or OMAP3_MODULE_GPTIMER10_FCLK.
  228  *      
  229  *      This function can enable either a functional or interface clock.
  230  *
  231  *      The real work done to enable the clock is really done in the callback
  232  *      function associated with the clock, this function is simply a wrapper
  233  *      around that.
  234  *
  235  *      LOCKING:
  236  *      Internally locks the driver context.
  237  *
  238  *      RETURNS:
  239  *      Returns 0 on success or positive error code on failure.
  240  */
  241 int
  242 ti_prcm_clk_set_source(clk_ident_t clk, clk_src_t clksrc)
  243 {
  244         struct ti_clock_dev *clk_dev;
  245         int ret;
  246 
  247         /* Find the clock within the devmap - it's a bit inefficent having a for 
  248          * loop for this, but this function should only called when a driver is 
  249          * being activated so IMHO not a big issue.
  250          */
  251         clk_dev = ti_prcm_clk_dev(clk);
  252 
  253         /* Sanity check we managed to find the clock */
  254         if (clk_dev == NULL)
  255                 return (EINVAL);
  256 
  257         /* Activate the clock */
  258         if (clk_dev->clk_set_source)
  259                 ret = clk_dev->clk_set_source(clk_dev, clksrc);
  260         else
  261                 ret = EINVAL;
  262 
  263         return (ret);
  264 }
  265 
  266 
  267 /**
  268  *      ti_prcm_clk_get_source_freq - gets the source clock frequency
  269  *      @clk: identifier for the module to enable, see ti_prcm.h for a list
  270  *            of possible modules.
  271  *      @freq: pointer to an integer that upon return will contain the src freq
  272  *      
  273  *      This function returns the frequency of the source clock.
  274  *
  275  *      The real work done to enable the clock is really done in the callback
  276  *      function associated with the clock, this function is simply a wrapper
  277  *      around that.
  278  *
  279  *      LOCKING:
  280  *      Internally locks the driver context.
  281  *
  282  *      RETURNS:
  283  *      Returns 0 on success or positive error code on failure.
  284  */
  285 int
  286 ti_prcm_clk_get_source_freq(clk_ident_t clk, unsigned int *freq)
  287 {
  288         struct ti_clock_dev *clk_dev;
  289         int ret;
  290 
  291         /* Find the clock within the devmap - it's a bit inefficent having a for 
  292          * loop for this, but this function should only called when a driver is 
  293          * being activated so IMHO not a big issue.
  294          */
  295         clk_dev = ti_prcm_clk_dev(clk);
  296 
  297         /* Sanity check we managed to find the clock */
  298         if (clk_dev == NULL)
  299                 return (EINVAL);
  300 
  301         /* Get the source frequency of the clock */
  302         if (clk_dev->clk_get_source_freq)
  303                 ret = clk_dev->clk_get_source_freq(clk_dev, freq);
  304         else
  305                 ret = EINVAL;
  306         
  307         return (ret);
  308 }

Cache object: f2f1ee0d9694649d4154c3265d54b544


[ 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.