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/clk/ti_clk_clkctrl.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  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2020 Oskar Holmlund <oskar.holmlund@ohdata.se>
    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  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   20  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
   22  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   23  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  *
   27  * $FreeBSD$
   28  */
   29 
   30 #include <sys/cdefs.h>
   31 __FBSDID("$FreeBSD$");
   32 
   33 #include <sys/param.h>
   34 #include <sys/systm.h>
   35 #include <sys/bus.h>
   36 #include <sys/malloc.h>
   37 
   38 #include <dev/extres/clk/clk.h>
   39 
   40 #include <arm/ti/clk/ti_clk_clkctrl.h>
   41 
   42 #include "clkdev_if.h"
   43 
   44 #if 0
   45 #define DPRINTF(dev, msg...) device_printf(dev, msg)
   46 #else
   47 #define DPRINTF(dev, msg...)
   48 #endif
   49 
   50 /*
   51  * clknode for clkctrl, implements gate and mux (for gpioc)
   52  */
   53 
   54 #define GPIO_X_GDBCLK_MASK      0x00040000
   55 #define IDLEST_MASK             0x00030000
   56 #define MODULEMODE_MASK         0x00000003
   57 
   58 #define GPIOX_GDBCLK_ENABLE     0x00040000
   59 #define GPIOX_GDBCLK_DISABLE    0x00000000
   60 #define IDLEST_FUNC             0x00000000
   61 #define IDLEST_TRANS            0x00010000
   62 #define IDLEST_IDLE             0x00020000
   63 #define IDLEST_DISABLE          0x00030000
   64 
   65 #define MODULEMODE_DISABLE      0x0
   66 #define MODULEMODE_ENABLE       0x2
   67 
   68 struct ti_clkctrl_clknode_sc {
   69         device_t        dev;
   70         bool            gdbclk;
   71         /* omap4-cm range.host + ti,clkctrl reg[0] */
   72         uint32_t        register_offset;
   73 };
   74 
   75 #define WRITE4(_clk, off, val)                                          \
   76         CLKDEV_WRITE_4(clknode_get_device(_clk), off, val)
   77 #define READ4(_clk, off, val)                                           \
   78         CLKDEV_READ_4(clknode_get_device(_clk), off, val)
   79 #define DEVICE_LOCK(_clk)                                               \
   80         CLKDEV_DEVICE_LOCK(clknode_get_device(_clk))
   81 #define DEVICE_UNLOCK(_clk)                                             \
   82         CLKDEV_DEVICE_UNLOCK(clknode_get_device(_clk))
   83 
   84 static int
   85 ti_clkctrl_init(struct clknode *clk, device_t dev)
   86 {
   87         struct ti_clkctrl_clknode_sc *sc;
   88 
   89         sc = clknode_get_softc(clk);
   90         sc->dev = dev;
   91 
   92         clknode_init_parent_idx(clk, 0);
   93         return (0);
   94 }
   95 
   96 static int
   97 ti_clkctrl_set_gdbclk_gate(struct clknode *clk, bool enable)
   98 {
   99         struct ti_clkctrl_clknode_sc *sc;
  100         uint32_t val, gpio_x_gdbclk;
  101         uint32_t timeout = 100;
  102 
  103         sc = clknode_get_softc(clk);
  104 
  105         READ4(clk, sc->register_offset, &val);
  106         DPRINTF(sc->dev, "val(%x) & (%x | %x = %x)\n",
  107             val, GPIO_X_GDBCLK_MASK, MODULEMODE_MASK,
  108             GPIO_X_GDBCLK_MASK | MODULEMODE_MASK);
  109 
  110         if (enable) {
  111                 val = val & MODULEMODE_MASK;
  112                 val |= GPIOX_GDBCLK_ENABLE;
  113         } else {
  114                 val = val & MODULEMODE_MASK;
  115                 val |= GPIOX_GDBCLK_DISABLE;
  116         }
  117 
  118         DPRINTF(sc->dev, "val %x\n", val);
  119         WRITE4(clk, sc->register_offset, val);
  120 
  121         /* Wait */
  122         while (timeout) {
  123                 READ4(clk, sc->register_offset, &val);
  124                 gpio_x_gdbclk = val & GPIO_X_GDBCLK_MASK;
  125                 if (enable && (gpio_x_gdbclk == GPIOX_GDBCLK_ENABLE))
  126                         break;
  127                 else if (!enable && (gpio_x_gdbclk == GPIOX_GDBCLK_DISABLE))
  128                         break;
  129                 DELAY(10);
  130                 timeout--;
  131         }
  132         if (timeout == 0) {
  133                 device_printf(sc->dev, "ti_clkctrl_set_gdbclk_gate: Timeout\n");
  134                 return (1);
  135         }
  136 
  137         return (0);
  138 }
  139 
  140 static int
  141 ti_clkctrl_set_gate(struct clknode *clk, bool enable)
  142 {
  143         struct ti_clkctrl_clknode_sc *sc;
  144         uint32_t        val, idlest, module;
  145         uint32_t timeout=100;
  146         int err;
  147 
  148         sc = clknode_get_softc(clk);
  149 
  150         if (sc->gdbclk) {
  151                 err = ti_clkctrl_set_gdbclk_gate(clk, enable);
  152                 return (err);
  153         }
  154 
  155         READ4(clk, sc->register_offset, &val);
  156 
  157         if (enable)
  158                 WRITE4(clk, sc->register_offset, MODULEMODE_ENABLE);
  159         else
  160                 WRITE4(clk, sc->register_offset, MODULEMODE_DISABLE);
  161 
  162         while (timeout) {
  163                 READ4(clk, sc->register_offset, &val);
  164                 idlest = val & IDLEST_MASK;
  165                 module = val & MODULEMODE_MASK;
  166                 if (enable &&
  167                     (idlest == IDLEST_FUNC || idlest == IDLEST_TRANS) &&
  168                     module == MODULEMODE_ENABLE)
  169                         break;
  170                 else if (!enable &&
  171                     idlest == IDLEST_DISABLE &&
  172                     module == MODULEMODE_DISABLE)
  173                         break;
  174                 DELAY(10);
  175                 timeout--;
  176         }
  177 
  178         if (timeout == 0) {
  179                 device_printf(sc->dev, "ti_clkctrl_set_gate: Timeout\n");
  180                 return (1);
  181         }
  182 
  183         return (0);
  184 }
  185 
  186 static clknode_method_t ti_clkctrl_clknode_methods[] = {
  187         /* Device interface */
  188         CLKNODEMETHOD(clknode_init,     ti_clkctrl_init),
  189         CLKNODEMETHOD(clknode_set_gate, ti_clkctrl_set_gate),
  190         CLKNODEMETHOD_END
  191 };
  192 
  193 DEFINE_CLASS_1(ti_clkctrl_clknode, ti_clkctrl_clknode_class,
  194     ti_clkctrl_clknode_methods, sizeof(struct ti_clkctrl_clknode_sc),
  195     clknode_class);
  196 
  197 int
  198 ti_clknode_clkctrl_register(struct clkdom *clkdom,
  199     struct ti_clk_clkctrl_def *clkdef)
  200 {
  201         struct clknode *clk;
  202         struct ti_clkctrl_clknode_sc *sc;
  203 
  204         clk = clknode_create(clkdom, &ti_clkctrl_clknode_class,
  205             &clkdef->clkdef);
  206 
  207         if (clk == NULL) {
  208                 return (1);
  209         }
  210 
  211         sc = clknode_get_softc(clk);
  212         sc->register_offset = clkdef->register_offset;
  213         sc->gdbclk = clkdef->gdbclk;
  214 
  215         if (clknode_register(clkdom, clk) == NULL) {
  216                 return (2);
  217         }
  218         return (0);
  219 }

Cache object: 9d0a564711f3292dc67b0e3d4127f367


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