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/freescale/vybrid/vf_anadig.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) 2013-2014 Ruslan Bukin <br@bsdpad.com>
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  */
   26 
   27 /*
   28  * Vybrid Family Analog components control digital interface (ANADIG)
   29  * Chapter 11, Vybrid Reference Manual, Rev. 5, 07/2013
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __FBSDID("$FreeBSD: releng/11.1/sys/arm/freescale/vybrid/vf_anadig.c 281085 2015-04-04 21:34:26Z andrew $");
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/bus.h>
   38 #include <sys/kernel.h>
   39 #include <sys/module.h>
   40 #include <sys/malloc.h>
   41 #include <sys/rman.h>
   42 #include <sys/timeet.h>
   43 #include <sys/timetc.h>
   44 #include <sys/watchdog.h>
   45 
   46 #include <dev/fdt/fdt_common.h>
   47 #include <dev/ofw/openfirm.h>
   48 #include <dev/ofw/ofw_bus.h>
   49 #include <dev/ofw/ofw_bus_subr.h>
   50 
   51 #include <machine/bus.h>
   52 #include <machine/cpu.h>
   53 #include <machine/intr.h>
   54 
   55 #include <arm/freescale/vybrid/vf_common.h>
   56 
   57 #define ANADIG_PLL3_CTRL        0x010   /* PLL3 Control */
   58 #define ANADIG_PLL7_CTRL        0x020   /* PLL7 Control */
   59 #define ANADIG_PLL2_CTRL        0x030   /* PLL2 Control */
   60 #define ANADIG_PLL2_SS          0x040   /* PLL2 Spread Spectrum */
   61 #define ANADIG_PLL2_NUM         0x050   /* PLL2 Numerator */
   62 #define ANADIG_PLL2_DENOM       0x060   /* PLL2 Denominator */
   63 #define ANADIG_PLL4_CTRL        0x070   /* PLL4 Control */
   64 #define ANADIG_PLL4_NUM         0x080   /* PLL4 Numerator */
   65 #define ANADIG_PLL4_DENOM       0x090   /* PLL4 Denominator */
   66 #define ANADIG_PLL6_CTRL        0x0A0   /* PLL6 Control */
   67 #define ANADIG_PLL6_NUM         0x0B0   /* PLL6 Numerator */
   68 #define ANADIG_PLL6_DENOM       0x0C0   /* PLL6 Denominator */
   69 #define ANADIG_PLL5_CTRL        0x0E0   /* PLL5 Control */
   70 #define ANADIG_PLL3_PFD         0x0F0   /* PLL3 PFD */
   71 #define ANADIG_PLL2_PFD         0x100   /* PLL2 PFD */
   72 #define ANADIG_REG_1P1          0x110   /* Regulator 1P1 */
   73 #define ANADIG_REG_3P0          0x120   /* Regulator 3P0 */
   74 #define ANADIG_REG_2P5          0x130   /* Regulator 2P5 */
   75 #define ANADIG_ANA_MISC0        0x150   /* Analog Miscellaneous */
   76 #define ANADIG_ANA_MISC1        0x160   /* Analog Miscellaneous */
   77 #define ANADIG_ANADIG_DIGPROG   0x260   /* Digital Program */
   78 #define ANADIG_PLL1_CTRL        0x270   /* PLL1 Control */
   79 #define ANADIG_PLL1_SS          0x280   /* PLL1 Spread Spectrum */
   80 #define ANADIG_PLL1_NUM         0x290   /* PLL1 Numerator */
   81 #define ANADIG_PLL1_DENOM       0x2A0   /* PLL1 Denominator */
   82 #define ANADIG_PLL1_PFD         0x2B0   /* PLL1_PFD */
   83 #define ANADIG_PLL_LOCK         0x2C0   /* PLL Lock */
   84 
   85 #define USB_VBUS_DETECT(n)              (0x1A0 + 0x60 * n)
   86 #define USB_CHRG_DETECT(n)              (0x1B0 + 0x60 * n)
   87 #define USB_VBUS_DETECT_STATUS(n)       (0x1C0 + 0x60 * n)
   88 #define USB_CHRG_DETECT_STATUS(n)       (0x1D0 + 0x60 * n)
   89 #define USB_LOOPBACK(n)                 (0x1E0 + 0x60 * n)
   90 #define USB_MISC(n)                     (0x1F0 + 0x60 * n)
   91 
   92 #define ANADIG_PLL_LOCKED       (1U << 31)
   93 #define ENABLE_LINREG           (1 << 0)
   94 #define EN_CLK_TO_UTMI          (1 << 30)
   95 
   96 #define CTRL_BYPASS             (1 << 16)
   97 #define CTRL_PWR                (1 << 12)
   98 #define CTRL_PLL_EN             (1 << 13)
   99 #define EN_USB_CLKS             (1 << 6)
  100 
  101 #define PLL4_CTRL_DIV_SEL_S     0
  102 #define PLL4_CTRL_DIV_SEL_M     0x7f
  103 
  104 struct anadig_softc {
  105         struct resource         *res[1];
  106         bus_space_tag_t         bst;
  107         bus_space_handle_t      bsh;
  108 };
  109 
  110 struct anadig_softc *anadig_sc;
  111 
  112 static struct resource_spec anadig_spec[] = {
  113         { SYS_RES_MEMORY,       0,      RF_ACTIVE },
  114         { -1, 0 }
  115 };
  116 
  117 static int
  118 anadig_probe(device_t dev)
  119 {
  120 
  121         if (!ofw_bus_status_okay(dev))
  122                 return (ENXIO);
  123 
  124         if (!ofw_bus_is_compatible(dev, "fsl,mvf600-anadig"))
  125                 return (ENXIO);
  126 
  127         device_set_desc(dev, "Vybrid Family ANADIG Unit");
  128         return (BUS_PROBE_DEFAULT);
  129 }
  130 
  131 static int
  132 enable_pll(struct anadig_softc *sc, int pll_ctrl)
  133 {
  134         int reg;
  135 
  136         reg = READ4(sc, pll_ctrl);
  137         reg &= ~(CTRL_BYPASS | CTRL_PWR);
  138         if (pll_ctrl == ANADIG_PLL3_CTRL || pll_ctrl == ANADIG_PLL7_CTRL) {
  139                 /* It is USB PLL. Power bit logic is reversed */
  140                 reg |= (CTRL_PWR | EN_USB_CLKS);
  141         }
  142         WRITE4(sc, pll_ctrl, reg);
  143 
  144         /* Wait for PLL lock */
  145         while (!(READ4(sc, pll_ctrl) & ANADIG_PLL_LOCKED))
  146                 ;
  147 
  148         reg = READ4(sc, pll_ctrl);
  149         reg |= (CTRL_PLL_EN);
  150         WRITE4(sc, pll_ctrl, reg);
  151 
  152         return (0);
  153 }
  154 
  155 uint32_t
  156 pll4_configure_output(uint32_t mfi, uint32_t mfn, uint32_t mfd)
  157 {
  158         struct anadig_softc *sc;
  159         int reg;
  160 
  161         sc = anadig_sc;
  162 
  163         /*
  164          * PLLout = Fsys * (MFI+(MFN/MFD))
  165          */
  166 
  167         reg = READ4(sc, ANADIG_PLL4_CTRL);
  168         reg &= ~(PLL4_CTRL_DIV_SEL_M << PLL4_CTRL_DIV_SEL_S);
  169         reg |= (mfi << PLL4_CTRL_DIV_SEL_S);
  170         WRITE4(sc, ANADIG_PLL4_CTRL, reg);
  171         WRITE4(sc, ANADIG_PLL4_NUM, mfn);
  172         WRITE4(sc, ANADIG_PLL4_DENOM, mfd);
  173 
  174         return (0);
  175 }
  176 
  177 static int
  178 anadig_attach(device_t dev)
  179 {
  180         struct anadig_softc *sc;
  181         int reg;
  182 
  183         sc = device_get_softc(dev);
  184 
  185         if (bus_alloc_resources(dev, anadig_spec, sc->res)) {
  186                 device_printf(dev, "could not allocate resources\n");
  187                 return (ENXIO);
  188         }
  189 
  190         /* Memory interface */
  191         sc->bst = rman_get_bustag(sc->res[0]);
  192         sc->bsh = rman_get_bushandle(sc->res[0]);
  193 
  194         anadig_sc = sc;
  195 
  196         /* Enable USB PLLs */
  197         enable_pll(sc, ANADIG_PLL3_CTRL);
  198         enable_pll(sc, ANADIG_PLL7_CTRL);
  199 
  200         /* Enable other PLLs */
  201         enable_pll(sc, ANADIG_PLL1_CTRL);
  202         enable_pll(sc, ANADIG_PLL2_CTRL);
  203         enable_pll(sc, ANADIG_PLL4_CTRL);
  204         enable_pll(sc, ANADIG_PLL5_CTRL);
  205         enable_pll(sc, ANADIG_PLL6_CTRL);
  206 
  207         /* Enable USB voltage regulator */
  208         reg = READ4(sc, ANADIG_REG_3P0);
  209         reg |= (ENABLE_LINREG);
  210         WRITE4(sc, ANADIG_REG_3P0, reg);
  211 
  212         /* Give clocks to USB */
  213         reg = READ4(sc, USB_MISC(0));
  214         reg |= (EN_CLK_TO_UTMI);
  215         WRITE4(sc, USB_MISC(0), reg);
  216 
  217         reg = READ4(sc, USB_MISC(1));
  218         reg |= (EN_CLK_TO_UTMI);
  219         WRITE4(sc, USB_MISC(1), reg);
  220 
  221 #if 0
  222         printf("USB_ANALOG_USB_MISC(0) == 0x%08x\n",
  223             READ4(sc, USB_ANALOG_USB_MISC(0)));
  224         printf("USB_ANALOG_USB_MISC(1) == 0x%08x\n",
  225             READ4(sc, USB_ANALOG_USB_MISC(1)));
  226 #endif
  227 
  228         return (0);
  229 }
  230 
  231 static device_method_t anadig_methods[] = {
  232         DEVMETHOD(device_probe,         anadig_probe),
  233         DEVMETHOD(device_attach,        anadig_attach),
  234         { 0, 0 }
  235 };
  236 
  237 static driver_t anadig_driver = {
  238         "anadig",
  239         anadig_methods,
  240         sizeof(struct anadig_softc),
  241 };
  242 
  243 static devclass_t anadig_devclass;
  244 
  245 DRIVER_MODULE(anadig, simplebus, anadig_driver, anadig_devclass, 0, 0);

Cache object: 36a6322334c60e0a98189716b432e774


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