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/arm64/rockchip/rk_pinctrl.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) 2018 Emmanuel Vadot <manu@FreeBSD.org>
    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 AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, 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  */
   28 
   29 #include <sys/cdefs.h>
   30 __FBSDID("$FreeBSD$");
   31 
   32 #include <sys/param.h>
   33 #include <sys/systm.h>
   34 #include <sys/bus.h>
   35 
   36 #include <sys/gpio.h>
   37 #include <sys/kernel.h>
   38 #include <sys/lock.h>
   39 #include <sys/module.h>
   40 #include <sys/mutex.h>
   41 #include <sys/rman.h>
   42 
   43 #include <machine/bus.h>
   44 #include <machine/resource.h>
   45 #include <machine/intr.h>
   46 
   47 #include <dev/fdt/simplebus.h>
   48 
   49 #include <dev/ofw/ofw_bus.h>
   50 #include <dev/ofw/ofw_bus_subr.h>
   51 
   52 #include <dev/fdt/fdt_pinctrl.h>
   53 
   54 #include <dev/extres/syscon/syscon.h>
   55 
   56 #include "gpio_if.h"
   57 #include "syscon_if.h"
   58 #include "fdt_pinctrl_if.h"
   59 
   60 struct rk_pinctrl_pin_drive {
   61         uint32_t        bank;
   62         uint32_t        subbank;
   63         uint32_t        offset;
   64         uint32_t        value;
   65         uint32_t        ma;
   66 };
   67 
   68 struct rk_pinctrl_bank {
   69         uint32_t        bank;
   70         uint32_t        subbank;
   71         uint32_t        offset;
   72         uint32_t        nbits;
   73 };
   74 
   75 struct rk_pinctrl_pin_fixup {
   76         uint32_t        bank;
   77         uint32_t        subbank;
   78         uint32_t        pin;
   79         uint32_t        reg;
   80         uint32_t        bit;
   81         uint32_t        mask;
   82 };
   83 
   84 struct rk_pinctrl_gpio {
   85         uint32_t        bank;
   86         char            *gpio_name;
   87         device_t        gpio_dev;
   88 };
   89 
   90 struct rk_pinctrl_softc;
   91 
   92 struct rk_pinctrl_conf {
   93         struct rk_pinctrl_bank          *iomux_conf;
   94         uint32_t                        iomux_nbanks;
   95         struct rk_pinctrl_pin_fixup     *pin_fixup;
   96         uint32_t                        npin_fixup;
   97         struct rk_pinctrl_pin_drive     *pin_drive;
   98         uint32_t                        npin_drive;
   99         struct rk_pinctrl_gpio          *gpio_bank;
  100         uint32_t                        ngpio_bank;
  101         uint32_t        (*get_pd_offset)(struct rk_pinctrl_softc *, uint32_t);
  102         struct syscon   *(*get_syscon)(struct rk_pinctrl_softc *, uint32_t);
  103         int             (*parse_bias)(phandle_t, int);
  104         int             (*resolv_bias_value)(int, int);
  105         int             (*get_bias_value)(int, int);
  106 };
  107 
  108 struct rk_pinctrl_softc {
  109         struct simplebus_softc  simplebus_sc;
  110         device_t                dev;
  111         struct syscon           *grf;
  112         struct syscon           *pmu;
  113         struct rk_pinctrl_conf  *conf;
  114         struct mtx              mtx;
  115 };
  116 
  117 #define RK_PINCTRL_LOCK(_sc)            mtx_lock_spin(&(_sc)->mtx)
  118 #define RK_PINCTRL_UNLOCK(_sc)          mtx_unlock_spin(&(_sc)->mtx)
  119 #define RK_PINCTRL_LOCK_ASSERT(_sc)     mtx_assert(&(_sc)->mtx, MA_OWNED)
  120 
  121 #define RK_IOMUX(_bank, _subbank, _offset, _nbits)                      \
  122 {                                                                       \
  123         .bank = _bank,                                                  \
  124         .subbank = _subbank,                                            \
  125         .offset = _offset,                                              \
  126         .nbits = _nbits,                                                \
  127 }
  128 
  129 #define RK_PINFIX(_bank, _pin, _reg, _bit, _mask)                       \
  130 {                                                                       \
  131         .bank = _bank,                                                  \
  132         .pin = _pin,                                                    \
  133         .reg = _reg,                                                    \
  134         .bit = _bit,                                                    \
  135         .mask = _mask,                                                  \
  136 }
  137 
  138 #define RK_PINDRIVE(_bank, _subbank, _offset, _value, _ma)              \
  139 {                                                                       \
  140         .bank = _bank,                                                  \
  141         .subbank = _subbank,                                            \
  142         .offset = _offset,                                              \
  143         .value = _value,                                                \
  144         .ma = _ma,                                                      \
  145 }
  146 #define RK_GPIO(_bank, _name)                                           \
  147 {                                                                       \
  148         .bank = _bank,                                                  \
  149         .gpio_name = _name,                                             \
  150 }
  151 
  152 static struct rk_pinctrl_gpio rk3288_gpio_bank[] = {
  153         RK_GPIO(0, "gpio0"),
  154         RK_GPIO(1, "gpio1"),
  155         RK_GPIO(2, "gpio2"),
  156         RK_GPIO(3, "gpio3"),
  157         RK_GPIO(4, "gpio4"),
  158         RK_GPIO(5, "gpio5"),
  159         RK_GPIO(6, "gpio6"),
  160         RK_GPIO(7, "gpio7"),
  161         RK_GPIO(8, "gpio8"),
  162 };
  163 
  164 static struct rk_pinctrl_bank rk3288_iomux_bank[] = {
  165         /*    bank sub  offs   nbits */
  166         /* PMU */
  167         RK_IOMUX(0, 0, 0x0084, 2),
  168         RK_IOMUX(0, 1, 0x0088, 2),
  169         RK_IOMUX(0, 2, 0x008C, 2),
  170         /* GFR */
  171         RK_IOMUX(1, 3, 0x000C, 2),
  172         RK_IOMUX(2, 0, 0x0010, 2),
  173         RK_IOMUX(2, 1, 0x0014, 2),
  174         RK_IOMUX(2, 2, 0x0018, 2),
  175         RK_IOMUX(2, 3, 0x001C, 2),
  176         RK_IOMUX(3, 0, 0x0020, 2),
  177         RK_IOMUX(3, 1, 0x0024, 2),
  178         RK_IOMUX(3, 2, 0x0028, 2),
  179         RK_IOMUX(3, 3, 0x002C, 4),
  180         RK_IOMUX(4, 0, 0x0034, 4),
  181         RK_IOMUX(4, 1, 0x003C, 4),
  182         RK_IOMUX(4, 2, 0x0044, 2),
  183         RK_IOMUX(4, 3, 0x0048, 2),
  184         /* 5,0 - Empty */
  185         RK_IOMUX(5, 1, 0x0050, 2),
  186         RK_IOMUX(5, 2, 0x0054, 2),
  187         /* 5,3 - Empty */
  188         RK_IOMUX(6, 0, 0x005C, 2),
  189         RK_IOMUX(6, 1, 0x0060, 2),
  190         RK_IOMUX(6, 2, 0x0064, 2),
  191         /* 6,3 - Empty */
  192         RK_IOMUX(7, 0, 0x006C, 2),
  193         RK_IOMUX(7, 1, 0x0070, 2),
  194         RK_IOMUX(7, 2, 0x0074, 4),
  195         /* 7,3 - Empty */
  196         RK_IOMUX(8, 0, 0x0080, 2),
  197         RK_IOMUX(8, 1, 0x0084, 2),
  198         /* 8,2 - Empty */
  199         /* 8,3 - Empty */
  200 
  201 };
  202 
  203 static struct rk_pinctrl_pin_fixup rk3288_pin_fixup[] = {
  204 };
  205 
  206 static struct rk_pinctrl_pin_drive rk3288_pin_drive[] = {
  207         /*       bank sub offs val ma */
  208         /* GPIO0A (PMU)*/
  209         RK_PINDRIVE(0, 0, 0x070, 0, 2),
  210         RK_PINDRIVE(0, 0, 0x070, 1, 4),
  211         RK_PINDRIVE(0, 0, 0x070, 2, 8),
  212         RK_PINDRIVE(0, 0, 0x070, 3, 12),
  213 
  214         /* GPIO0B (PMU)*/
  215         RK_PINDRIVE(0, 1, 0x074, 0, 2),
  216         RK_PINDRIVE(0, 1, 0x074, 1, 4),
  217         RK_PINDRIVE(0, 1, 0x074, 2, 8),
  218         RK_PINDRIVE(0, 1, 0x074, 3, 12),
  219 
  220         /* GPIO0C (PMU)*/
  221         RK_PINDRIVE(0, 2, 0x078, 0, 2),
  222         RK_PINDRIVE(0, 2, 0x078, 1, 4),
  223         RK_PINDRIVE(0, 2, 0x078, 2, 8),
  224         RK_PINDRIVE(0, 2, 0x078, 3, 12),
  225 
  226         /* GPIO1D */
  227         RK_PINDRIVE(1, 3, 0x1CC, 0, 2),
  228         RK_PINDRIVE(1, 3, 0x1CC, 1, 4),
  229         RK_PINDRIVE(1, 3, 0x1CC, 2, 8),
  230         RK_PINDRIVE(1, 3, 0x1CC, 3, 12),
  231 
  232         /* GPIO2A */
  233         RK_PINDRIVE(2, 0, 0x1D0, 0, 2),
  234         RK_PINDRIVE(2, 0, 0x1D0, 1, 4),
  235         RK_PINDRIVE(2, 0, 0x1D0, 2, 8),
  236         RK_PINDRIVE(2, 0, 0x1D0, 3, 12),
  237 
  238         /* GPIO2B */
  239         RK_PINDRIVE(2, 1, 0x1D4, 0, 2),
  240         RK_PINDRIVE(2, 1, 0x1D4, 1, 4),
  241         RK_PINDRIVE(2, 1, 0x1D4, 2, 8),
  242         RK_PINDRIVE(2, 1, 0x1D4, 3, 12),
  243 
  244         /* GPIO2C */
  245         RK_PINDRIVE(2, 2, 0x1D8, 0, 2),
  246         RK_PINDRIVE(2, 2, 0x1D8, 1, 4),
  247         RK_PINDRIVE(2, 2, 0x1D8, 2, 8),
  248         RK_PINDRIVE(2, 2, 0x1D8, 3, 12),
  249 
  250         /* GPIO2D */
  251         RK_PINDRIVE(2, 3, 0x1DC, 0, 2),
  252         RK_PINDRIVE(2, 3, 0x1DC, 1, 4),
  253         RK_PINDRIVE(2, 3, 0x1DC, 2, 8),
  254         RK_PINDRIVE(2, 3, 0x1DC, 3, 12),
  255 
  256         /* GPIO3A */
  257         RK_PINDRIVE(3, 0, 0x1E0, 0, 2),
  258         RK_PINDRIVE(3, 0, 0x1E0, 1, 4),
  259         RK_PINDRIVE(3, 0, 0x1E0, 2, 8),
  260         RK_PINDRIVE(3, 0, 0x1E0, 3, 12),
  261 
  262         /* GPIO3B */
  263         RK_PINDRIVE(3, 1, 0x1E4, 0, 2),
  264         RK_PINDRIVE(3, 1, 0x1E4, 1, 4),
  265         RK_PINDRIVE(3, 1, 0x1E4, 2, 8),
  266         RK_PINDRIVE(3, 1, 0x1E4, 3, 12),
  267 
  268         /* GPIO3C */
  269         RK_PINDRIVE(3, 2, 0x1E8, 0, 2),
  270         RK_PINDRIVE(3, 2, 0x1E8, 1, 4),
  271         RK_PINDRIVE(3, 2, 0x1E8, 2, 8),
  272         RK_PINDRIVE(3, 2, 0x1E8, 3, 12),
  273 
  274         /* GPIO3D */
  275         RK_PINDRIVE(3, 3, 0x1EC, 0, 2),
  276         RK_PINDRIVE(3, 3, 0x1EC, 1, 4),
  277         RK_PINDRIVE(3, 3, 0x1EC, 2, 8),
  278         RK_PINDRIVE(3, 3, 0x1EC, 3, 12),
  279 
  280         /* GPIO4A */
  281         RK_PINDRIVE(4, 0, 0x1F0, 0, 2),
  282         RK_PINDRIVE(4, 0, 0x1F0, 1, 4),
  283         RK_PINDRIVE(4, 0, 0x1F0, 2, 8),
  284         RK_PINDRIVE(4, 0, 0x1F0, 3, 12),
  285 
  286         /* GPIO4B */
  287         RK_PINDRIVE(4, 1, 0x1F4, 0, 2),
  288         RK_PINDRIVE(4, 1, 0x1F4, 1, 4),
  289         RK_PINDRIVE(4, 1, 0x1F4, 2, 8),
  290         RK_PINDRIVE(4, 1, 0x1F4, 3, 12),
  291 
  292         /* GPIO4C */
  293         RK_PINDRIVE(4, 2, 0x1F8, 0, 2),
  294         RK_PINDRIVE(4, 2, 0x1F8, 1, 4),
  295         RK_PINDRIVE(4, 2, 0x1F8, 2, 8),
  296         RK_PINDRIVE(4, 2, 0x1F8, 3, 12),
  297 
  298         /* GPIO4D */
  299         RK_PINDRIVE(4, 3, 0x1FC, 0, 2),
  300         RK_PINDRIVE(4, 3, 0x1FC, 1, 4),
  301         RK_PINDRIVE(4, 3, 0x1FC, 2, 8),
  302         RK_PINDRIVE(4, 3, 0x1FC, 3, 12),
  303 
  304         /* GPIO5B */
  305         RK_PINDRIVE(5, 1, 0x204, 0, 2),
  306         RK_PINDRIVE(5, 1, 0x204, 1, 4),
  307         RK_PINDRIVE(5, 1, 0x204, 2, 8),
  308         RK_PINDRIVE(5, 1, 0x204, 3, 12),
  309 
  310         /* GPIO5C */
  311         RK_PINDRIVE(5, 2, 0x208, 0, 2),
  312         RK_PINDRIVE(5, 2, 0x208, 1, 4),
  313         RK_PINDRIVE(5, 2, 0x208, 2, 8),
  314         RK_PINDRIVE(5, 2, 0x208, 3, 12),
  315 
  316         /* GPIO6A */
  317         RK_PINDRIVE(6, 0, 0x210, 0, 2),
  318         RK_PINDRIVE(6, 0, 0x210, 1, 4),
  319         RK_PINDRIVE(6, 0, 0x210, 2, 8),
  320         RK_PINDRIVE(6, 0, 0x210, 3, 12),
  321 
  322         /* GPIO6B */
  323         RK_PINDRIVE(6, 1, 0x214, 0, 2),
  324         RK_PINDRIVE(6, 1, 0x214, 1, 4),
  325         RK_PINDRIVE(6, 1, 0x214, 2, 8),
  326         RK_PINDRIVE(6, 1, 0x214, 3, 12),
  327 
  328         /* GPIO6C */
  329         RK_PINDRIVE(6, 2, 0x218, 0, 2),
  330         RK_PINDRIVE(6, 2, 0x218, 1, 4),
  331         RK_PINDRIVE(6, 2, 0x218, 2, 8),
  332         RK_PINDRIVE(6, 2, 0x218, 3, 12),
  333 
  334         /* GPIO7A */
  335         RK_PINDRIVE(7, 0, 0x220, 0, 2),
  336         RK_PINDRIVE(7, 0, 0x220, 1, 4),
  337         RK_PINDRIVE(7, 0, 0x220, 2, 8),
  338         RK_PINDRIVE(7, 0, 0x220, 3, 12),
  339 
  340         /* GPIO7B */
  341         RK_PINDRIVE(7, 1, 0x224, 0, 2),
  342         RK_PINDRIVE(7, 1, 0x224, 1, 4),
  343         RK_PINDRIVE(7, 1, 0x224, 2, 8),
  344         RK_PINDRIVE(7, 1, 0x224, 3, 12),
  345 
  346         /* GPIO7C */
  347         RK_PINDRIVE(7, 2, 0x228, 0, 2),
  348         RK_PINDRIVE(7, 2, 0x228, 1, 4),
  349         RK_PINDRIVE(7, 2, 0x228, 2, 8),
  350         RK_PINDRIVE(7, 2, 0x228, 3, 12),
  351 
  352         /* GPIO8A */
  353         RK_PINDRIVE(8, 0, 0x230, 0, 2),
  354         RK_PINDRIVE(8, 0, 0x230, 1, 4),
  355         RK_PINDRIVE(8, 0, 0x230, 2, 8),
  356         RK_PINDRIVE(8, 0, 0x230, 3, 12),
  357 
  358         /* GPIO8B */
  359         RK_PINDRIVE(8, 1, 0x234, 0, 2),
  360         RK_PINDRIVE(8, 1, 0x234, 1, 4),
  361         RK_PINDRIVE(8, 1, 0x234, 2, 8),
  362         RK_PINDRIVE(8, 1, 0x234, 3, 12),
  363 };
  364 
  365 static uint32_t
  366 rk3288_get_pd_offset(struct rk_pinctrl_softc *sc, uint32_t bank)
  367 {
  368         if (bank == 0)
  369                 return (0x064);         /* PMU */
  370         return (0x130);
  371 }
  372 
  373 static struct syscon *
  374 rk3288_get_syscon(struct rk_pinctrl_softc *sc, uint32_t bank)
  375 {
  376         if (bank == 0)
  377                 return (sc->pmu);
  378         return (sc->grf);
  379 }
  380 
  381 static int
  382 rk3288_parse_bias(phandle_t node, int bank)
  383 {
  384         if (OF_hasprop(node, "bias-disable"))
  385                 return (0);
  386         if (OF_hasprop(node, "bias-pull-up"))
  387                 return (1);
  388         if (OF_hasprop(node, "bias-pull-down"))
  389                 return (2);
  390 
  391         return (-1);
  392 }
  393 
  394 static int
  395 rk3288_resolv_bias_value(int bank, int bias)
  396 {
  397         int rv = 0;
  398 
  399         if (bias == 1)
  400                 rv = GPIO_PIN_PULLUP;
  401         else if (bias == 2)
  402                 rv = GPIO_PIN_PULLDOWN;
  403 
  404         return (rv);
  405 }
  406 
  407 static int
  408 rk3288_get_bias_value(int bank, int bias)
  409 {
  410         int rv = 0;
  411 
  412         if (bias & GPIO_PIN_PULLUP)
  413                 rv = 1;
  414         else if (bias & GPIO_PIN_PULLDOWN)
  415                 rv = 2;
  416 
  417         return (rv);
  418 }
  419 
  420 struct rk_pinctrl_conf rk3288_conf = {
  421         .iomux_conf = rk3288_iomux_bank,
  422         .iomux_nbanks = nitems(rk3288_iomux_bank),
  423         .pin_fixup = rk3288_pin_fixup,
  424         .npin_fixup = nitems(rk3288_pin_fixup),
  425         .pin_drive = rk3288_pin_drive,
  426         .npin_drive = nitems(rk3288_pin_drive),
  427         .gpio_bank = rk3288_gpio_bank,
  428         .ngpio_bank = nitems(rk3288_gpio_bank),
  429         .get_pd_offset = rk3288_get_pd_offset,
  430         .get_syscon = rk3288_get_syscon,
  431         .parse_bias = rk3288_parse_bias,
  432         .resolv_bias_value = rk3288_resolv_bias_value,
  433         .get_bias_value = rk3288_get_bias_value,
  434 };
  435 
  436 static struct rk_pinctrl_gpio rk3328_gpio_bank[] = {
  437         RK_GPIO(0, "gpio0"),
  438         RK_GPIO(1, "gpio1"),
  439         RK_GPIO(2, "gpio2"),
  440         RK_GPIO(3, "gpio3"),
  441 };
  442 
  443 static struct rk_pinctrl_bank rk3328_iomux_bank[] = {
  444         /*    bank sub offs nbits */
  445         RK_IOMUX(0, 0, 0x0000, 2),
  446         RK_IOMUX(0, 1, 0x0004, 2),
  447         RK_IOMUX(0, 2, 0x0008, 2),
  448         RK_IOMUX(0, 3, 0x000C, 2),
  449         RK_IOMUX(1, 0, 0x0010, 2),
  450         RK_IOMUX(1, 1, 0x0014, 2),
  451         RK_IOMUX(1, 2, 0x0018, 2),
  452         RK_IOMUX(1, 3, 0x001C, 2),
  453         RK_IOMUX(2, 0, 0x0020, 2),
  454         RK_IOMUX(2, 1, 0x0024, 3),
  455         RK_IOMUX(2, 2, 0x002c, 3),
  456         RK_IOMUX(2, 3, 0x0034, 2),
  457         RK_IOMUX(3, 0, 0x0038, 3),
  458         RK_IOMUX(3, 1, 0x0040, 3),
  459         RK_IOMUX(3, 2, 0x0048, 2),
  460         RK_IOMUX(3, 3, 0x004c, 2),
  461 };
  462 
  463 static struct rk_pinctrl_pin_fixup rk3328_pin_fixup[] = {
  464         /*      bank  pin reg  bit  mask */
  465         RK_PINFIX(2, 12, 0x24,  8, 0x300),
  466         RK_PINFIX(2, 15, 0x28,  0, 0x7),
  467         RK_PINFIX(2, 23, 0x30, 14, 0x6000),
  468 };
  469 
  470 static struct rk_pinctrl_pin_drive rk3328_pin_drive[] = {
  471         /*       bank sub  offs val ma */
  472         RK_PINDRIVE(0, 0, 0x200, 0, 2),
  473         RK_PINDRIVE(0, 0, 0x200, 1, 4),
  474         RK_PINDRIVE(0, 0, 0x200, 2, 8),
  475         RK_PINDRIVE(0, 0, 0x200, 3, 12),
  476 
  477         RK_PINDRIVE(0, 1, 0x204, 0, 2),
  478         RK_PINDRIVE(0, 1, 0x204, 1, 4),
  479         RK_PINDRIVE(0, 1, 0x204, 2, 8),
  480         RK_PINDRIVE(0, 1, 0x204, 3, 12),
  481 
  482         RK_PINDRIVE(0, 2, 0x208, 0, 2),
  483         RK_PINDRIVE(0, 2, 0x208, 1, 4),
  484         RK_PINDRIVE(0, 2, 0x208, 2, 8),
  485         RK_PINDRIVE(0, 2, 0x208, 3, 12),
  486 
  487         RK_PINDRIVE(0, 3, 0x20C, 0, 2),
  488         RK_PINDRIVE(0, 3, 0x20C, 1, 4),
  489         RK_PINDRIVE(0, 3, 0x20C, 2, 8),
  490         RK_PINDRIVE(0, 3, 0x20C, 3, 12),
  491 
  492         RK_PINDRIVE(1, 0, 0x210, 0, 2),
  493         RK_PINDRIVE(1, 0, 0x210, 1, 4),
  494         RK_PINDRIVE(1, 0, 0x210, 2, 8),
  495         RK_PINDRIVE(1, 0, 0x210, 3, 12),
  496 
  497         RK_PINDRIVE(1, 1, 0x214, 0, 2),
  498         RK_PINDRIVE(1, 1, 0x214, 1, 4),
  499         RK_PINDRIVE(1, 1, 0x214, 2, 8),
  500         RK_PINDRIVE(1, 1, 0x214, 3, 12),
  501 
  502         RK_PINDRIVE(1, 2, 0x218, 0, 2),
  503         RK_PINDRIVE(1, 2, 0x218, 1, 4),
  504         RK_PINDRIVE(1, 2, 0x218, 2, 8),
  505         RK_PINDRIVE(1, 2, 0x218, 3, 12),
  506 
  507         RK_PINDRIVE(1, 3, 0x21C, 0, 2),
  508         RK_PINDRIVE(1, 3, 0x21C, 1, 4),
  509         RK_PINDRIVE(1, 3, 0x21C, 2, 8),
  510         RK_PINDRIVE(1, 3, 0x21C, 3, 12),
  511 
  512         RK_PINDRIVE(2, 0, 0x220, 0, 2),
  513         RK_PINDRIVE(2, 0, 0x220, 1, 4),
  514         RK_PINDRIVE(2, 0, 0x220, 2, 8),
  515         RK_PINDRIVE(2, 0, 0x220, 3, 12),
  516 
  517         RK_PINDRIVE(2, 1, 0x224, 0, 2),
  518         RK_PINDRIVE(2, 1, 0x224, 1, 4),
  519         RK_PINDRIVE(2, 1, 0x224, 2, 8),
  520         RK_PINDRIVE(2, 1, 0x224, 3, 12),
  521 
  522         RK_PINDRIVE(2, 2, 0x228, 0, 2),
  523         RK_PINDRIVE(2, 2, 0x228, 1, 4),
  524         RK_PINDRIVE(2, 2, 0x228, 2, 8),
  525         RK_PINDRIVE(2, 2, 0x228, 3, 12),
  526 
  527         RK_PINDRIVE(2, 3, 0x22C, 0, 2),
  528         RK_PINDRIVE(2, 3, 0x22C, 1, 4),
  529         RK_PINDRIVE(2, 3, 0x22C, 2, 8),
  530         RK_PINDRIVE(2, 3, 0x22C, 3, 12),
  531 
  532         RK_PINDRIVE(3, 0, 0x230, 0, 2),
  533         RK_PINDRIVE(3, 0, 0x230, 1, 4),
  534         RK_PINDRIVE(3, 0, 0x230, 2, 8),
  535         RK_PINDRIVE(3, 0, 0x230, 3, 12),
  536 
  537         RK_PINDRIVE(3, 1, 0x234, 0, 2),
  538         RK_PINDRIVE(3, 1, 0x234, 1, 4),
  539         RK_PINDRIVE(3, 1, 0x234, 2, 8),
  540         RK_PINDRIVE(3, 1, 0x234, 3, 12),
  541 
  542         RK_PINDRIVE(3, 2, 0x238, 0, 2),
  543         RK_PINDRIVE(3, 2, 0x238, 1, 4),
  544         RK_PINDRIVE(3, 2, 0x238, 2, 8),
  545         RK_PINDRIVE(3, 2, 0x238, 3, 12),
  546 
  547         RK_PINDRIVE(3, 3, 0x23C, 0, 2),
  548         RK_PINDRIVE(3, 3, 0x23C, 1, 4),
  549         RK_PINDRIVE(3, 3, 0x23C, 2, 8),
  550         RK_PINDRIVE(3, 3, 0x23C, 3, 12),
  551 };
  552 
  553 static uint32_t
  554 rk3328_get_pd_offset(struct rk_pinctrl_softc *sc, uint32_t bank)
  555 {
  556         return (0x100);
  557 }
  558 
  559 static struct syscon *
  560 rk3328_get_syscon(struct rk_pinctrl_softc *sc, uint32_t bank)
  561 {
  562         return (sc->grf);
  563 }
  564 
  565 struct rk_pinctrl_conf rk3328_conf = {
  566         .iomux_conf = rk3328_iomux_bank,
  567         .iomux_nbanks = nitems(rk3328_iomux_bank),
  568         .pin_fixup = rk3328_pin_fixup,
  569         .npin_fixup = nitems(rk3328_pin_fixup),
  570         .pin_drive = rk3328_pin_drive,
  571         .npin_drive = nitems(rk3328_pin_drive),
  572         .gpio_bank = rk3328_gpio_bank,
  573         .ngpio_bank = nitems(rk3328_gpio_bank),
  574         .get_pd_offset = rk3328_get_pd_offset,
  575         .get_syscon = rk3328_get_syscon,
  576         .parse_bias = rk3288_parse_bias,
  577         .resolv_bias_value = rk3288_resolv_bias_value,
  578         .get_bias_value = rk3288_get_bias_value,
  579 };
  580 
  581 static struct rk_pinctrl_gpio rk3399_gpio_bank[] = {
  582         RK_GPIO(0, "gpio0"),
  583         RK_GPIO(1, "gpio1"),
  584         RK_GPIO(2, "gpio2"),
  585         RK_GPIO(3, "gpio3"),
  586         RK_GPIO(4, "gpio4"),
  587 };
  588 
  589 static struct rk_pinctrl_bank rk3399_iomux_bank[] = {
  590         /*    bank sub  offs   nbits */
  591         RK_IOMUX(0, 0, 0x0000, 2),
  592         RK_IOMUX(0, 1, 0x0004, 2),
  593         RK_IOMUX(0, 2, 0x0008, 2),
  594         RK_IOMUX(0, 3, 0x000C, 2),
  595         RK_IOMUX(1, 0, 0x0010, 2),
  596         RK_IOMUX(1, 1, 0x0014, 2),
  597         RK_IOMUX(1, 2, 0x0018, 2),
  598         RK_IOMUX(1, 3, 0x001C, 2),
  599         RK_IOMUX(2, 0, 0xE000, 2),
  600         RK_IOMUX(2, 1, 0xE004, 2),
  601         RK_IOMUX(2, 2, 0xE008, 2),
  602         RK_IOMUX(2, 3, 0xE00C, 2),
  603         RK_IOMUX(3, 0, 0xE010, 2),
  604         RK_IOMUX(3, 1, 0xE014, 2),
  605         RK_IOMUX(3, 2, 0xE018, 2),
  606         RK_IOMUX(3, 3, 0xE01C, 2),
  607         RK_IOMUX(4, 0, 0xE020, 2),
  608         RK_IOMUX(4, 1, 0xE024, 2),
  609         RK_IOMUX(4, 2, 0xE028, 2),
  610         RK_IOMUX(4, 3, 0xE02C, 2),
  611 };
  612 
  613 static struct rk_pinctrl_pin_fixup rk3399_pin_fixup[] = {};
  614 
  615 static struct rk_pinctrl_pin_drive rk3399_pin_drive[] = {
  616         /*       bank sub offs val ma */
  617         /* GPIO0A */
  618         RK_PINDRIVE(0, 0, 0x80, 0, 5),
  619         RK_PINDRIVE(0, 0, 0x80, 1, 10),
  620         RK_PINDRIVE(0, 0, 0x80, 2, 15),
  621         RK_PINDRIVE(0, 0, 0x80, 3, 20),
  622 
  623         /* GPIOB */
  624         RK_PINDRIVE(0, 1, 0x88, 0, 5),
  625         RK_PINDRIVE(0, 1, 0x88, 1, 10),
  626         RK_PINDRIVE(0, 1, 0x88, 2, 15),
  627         RK_PINDRIVE(0, 1, 0x88, 3, 20),
  628 
  629         /* GPIO1A */
  630         RK_PINDRIVE(1, 0, 0xA0, 0, 3),
  631         RK_PINDRIVE(1, 0, 0xA0, 1, 6),
  632         RK_PINDRIVE(1, 0, 0xA0, 2, 9),
  633         RK_PINDRIVE(1, 0, 0xA0, 3, 12),
  634 
  635         /* GPIO1B */
  636         RK_PINDRIVE(1, 1, 0xA8, 0, 3),
  637         RK_PINDRIVE(1, 1, 0xA8, 1, 6),
  638         RK_PINDRIVE(1, 1, 0xA8, 2, 9),
  639         RK_PINDRIVE(1, 1, 0xA8, 3, 12),
  640 
  641         /* GPIO1C */
  642         RK_PINDRIVE(1, 2, 0xB0, 0, 3),
  643         RK_PINDRIVE(1, 2, 0xB0, 1, 6),
  644         RK_PINDRIVE(1, 2, 0xB0, 2, 9),
  645         RK_PINDRIVE(1, 2, 0xB0, 3, 12),
  646 
  647         /* GPIO1D */
  648         RK_PINDRIVE(1, 3, 0xB8, 0, 3),
  649         RK_PINDRIVE(1, 3, 0xB8, 1, 6),
  650         RK_PINDRIVE(1, 3, 0xB8, 2, 9),
  651         RK_PINDRIVE(1, 3, 0xB8, 3, 12),
  652 };
  653 
  654 static uint32_t
  655 rk3399_get_pd_offset(struct rk_pinctrl_softc *sc, uint32_t bank)
  656 {
  657         if (bank < 2)
  658                 return (0x40);
  659 
  660         return (0xE040);
  661 }
  662 
  663 static struct syscon *
  664 rk3399_get_syscon(struct rk_pinctrl_softc *sc, uint32_t bank)
  665 {
  666         if (bank < 2)
  667                 return (sc->pmu);
  668 
  669         return (sc->grf);
  670 }
  671 
  672 static int
  673 rk3399_parse_bias(phandle_t node, int bank)
  674 {
  675         int pullup, pulldown;
  676 
  677         if (OF_hasprop(node, "bias-disable"))
  678                 return (0);
  679 
  680         switch (bank) {
  681         case 0:
  682         case 2:
  683                 pullup = 3;
  684                 pulldown = 1;
  685                 break;
  686         case 1:
  687         case 3:
  688         case 4:
  689                 pullup = 1;
  690                 pulldown = 2;
  691                 break;
  692         }
  693 
  694         if (OF_hasprop(node, "bias-pull-up"))
  695                 return (pullup);
  696         if (OF_hasprop(node, "bias-pull-down"))
  697                 return (pulldown);
  698 
  699         return (-1);
  700 }
  701 
  702 static int
  703 rk3399_resolv_bias_value(int bank, int bias)
  704 {
  705         int rv = 0;
  706 
  707         switch (bank) {
  708         case 0:
  709         case 2:
  710                 if (bias == 3)
  711                         rv = GPIO_PIN_PULLUP;
  712                 else if (bias == 1)
  713                         rv = GPIO_PIN_PULLDOWN;
  714                 break;
  715         case 1:
  716         case 3:
  717         case 4:
  718                 if (bias == 1)
  719                         rv = GPIO_PIN_PULLUP;
  720                 else if (bias == 2)
  721                         rv = GPIO_PIN_PULLDOWN;
  722                 break;
  723         }
  724 
  725         return (rv);
  726 }
  727 
  728 static int
  729 rk3399_get_bias_value(int bank, int bias)
  730 {
  731         int rv = 0;
  732 
  733         switch (bank) {
  734         case 0:
  735         case 2:
  736                 if (bias & GPIO_PIN_PULLUP)
  737                         rv = 3;
  738                 else if (bias & GPIO_PIN_PULLDOWN)
  739                         rv = 1;
  740                 break;
  741         case 1:
  742         case 3:
  743         case 4:
  744                 if (bias & GPIO_PIN_PULLUP)
  745                         rv = 1;
  746                 else if (bias & GPIO_PIN_PULLDOWN)
  747                         rv = 2;
  748                 break;
  749         }
  750 
  751         return (rv);
  752 }
  753 
  754 struct rk_pinctrl_conf rk3399_conf = {
  755         .iomux_conf = rk3399_iomux_bank,
  756         .iomux_nbanks = nitems(rk3399_iomux_bank),
  757         .pin_fixup = rk3399_pin_fixup,
  758         .npin_fixup = nitems(rk3399_pin_fixup),
  759         .pin_drive = rk3399_pin_drive,
  760         .npin_drive = nitems(rk3399_pin_drive),
  761         .gpio_bank = rk3399_gpio_bank,
  762         .ngpio_bank = nitems(rk3399_gpio_bank),
  763         .get_pd_offset = rk3399_get_pd_offset,
  764         .get_syscon = rk3399_get_syscon,
  765         .parse_bias = rk3399_parse_bias,
  766         .resolv_bias_value = rk3399_resolv_bias_value,
  767         .get_bias_value = rk3399_get_bias_value,
  768 };
  769 
  770 #define GRF_IOFUNC_SEL0         0x0300
  771 #define  GMAC1_IOMUX_SEL_M0             0x01000000
  772 #define  GMAC1_IOMUX_SEL_M1             0x01000100
  773 
  774 static struct rk_pinctrl_gpio rk3568_gpio_bank[] = {
  775         RK_GPIO(0, "gpio0"),
  776         RK_GPIO(1, "gpio1"),
  777         RK_GPIO(2, "gpio2"),
  778         RK_GPIO(3, "gpio3"),
  779         RK_GPIO(4, "gpio4"),
  780 };
  781 
  782 static struct rk_pinctrl_bank rk3568_iomux_bank[] = {
  783         /*    bank sub  offs   nbits */
  784         RK_IOMUX(0, 0, 0x0000, 4),      /* PMU_GRF */
  785         RK_IOMUX(0, 1, 0x0008, 4),
  786         RK_IOMUX(0, 2, 0x0010, 4),
  787         RK_IOMUX(0, 3, 0x0018, 4),
  788 
  789         RK_IOMUX(1, 0, 0x0000, 4),      /* SYS_GRF */
  790         RK_IOMUX(1, 1, 0x0008, 4),
  791         RK_IOMUX(1, 2, 0x0010, 4),
  792         RK_IOMUX(1, 3, 0x0018, 4),
  793         RK_IOMUX(2, 0, 0x0020, 4),
  794         RK_IOMUX(2, 1, 0x0028, 4),
  795         RK_IOMUX(2, 2, 0x0030, 4),
  796         RK_IOMUX(2, 3, 0x0038, 4),
  797         RK_IOMUX(3, 0, 0x0040, 4),
  798         RK_IOMUX(3, 1, 0x0048, 4),
  799         RK_IOMUX(3, 2, 0x0050, 4),
  800         RK_IOMUX(3, 3, 0x0058, 4),
  801         RK_IOMUX(4, 0, 0x0060, 4),
  802         RK_IOMUX(4, 1, 0x0068, 4),
  803         RK_IOMUX(4, 2, 0x0070, 4),
  804         RK_IOMUX(4, 3, 0x0078, 4),
  805 };
  806 
  807 static struct rk_pinctrl_pin_fixup rk3568_pin_fixup[] = {};
  808 
  809 static struct rk_pinctrl_pin_drive rk3568_pin_drive[] = {
  810         /*       bank sub offs val ma */
  811         /* GPIO0A */
  812         RK_PINDRIVE(0, 0, 0x0020, 0, 2),
  813         RK_PINDRIVE(0, 0, 0x0020, 1, 4),
  814         RK_PINDRIVE(0, 0, 0x0020, 2, 8),
  815         RK_PINDRIVE(0, 0, 0x0020, 3, 12),
  816 
  817         /* GPIO0B */
  818         RK_PINDRIVE(0, 1, 0x0024, 0, 2),
  819         RK_PINDRIVE(0, 1, 0x0024, 1, 4),
  820         RK_PINDRIVE(0, 1, 0x0024, 2, 8),
  821         RK_PINDRIVE(0, 1, 0x0024, 3, 12),
  822 
  823         /* GPIO0C */
  824         RK_PINDRIVE(0, 1, 0x0028, 0, 2),
  825         RK_PINDRIVE(0, 1, 0x0028, 1, 4),
  826         RK_PINDRIVE(0, 1, 0x0028, 2, 8),
  827         RK_PINDRIVE(0, 1, 0x0028, 3, 12),
  828 
  829         /* GPIO0D */
  830         RK_PINDRIVE(0, 1, 0x002c, 0, 2),
  831         RK_PINDRIVE(0, 1, 0x002c, 1, 4),
  832         RK_PINDRIVE(0, 1, 0x002c, 2, 8),
  833         RK_PINDRIVE(0, 1, 0x002c, 3, 12),
  834 
  835         /* GPIO1A */
  836         RK_PINDRIVE(1, 0, 0x0080, 0, 2),
  837         RK_PINDRIVE(1, 0, 0x0080, 1, 4),
  838         RK_PINDRIVE(1, 0, 0x0080, 2, 8),
  839         RK_PINDRIVE(1, 0, 0x0080, 3, 12),
  840 
  841         /* GPIO1B */
  842         RK_PINDRIVE(1, 1, 0x0084, 0, 2),
  843         RK_PINDRIVE(1, 1, 0x0084, 1, 4),
  844         RK_PINDRIVE(1, 1, 0x0084, 2, 8),
  845         RK_PINDRIVE(1, 1, 0x0084, 3, 12),
  846 
  847         /* GPIO1C */
  848         RK_PINDRIVE(1, 2, 0x0088, 0, 2),
  849         RK_PINDRIVE(1, 2, 0x0088, 1, 4),
  850         RK_PINDRIVE(1, 2, 0x0088, 2, 8),
  851         RK_PINDRIVE(1, 2, 0x0088, 3, 12),
  852 
  853         /* GPIO1D */
  854         RK_PINDRIVE(1, 3, 0x008c, 0, 2),
  855         RK_PINDRIVE(1, 3, 0x008c, 1, 4),
  856         RK_PINDRIVE(1, 3, 0x008c, 2, 8),
  857         RK_PINDRIVE(1, 3, 0x008c, 3, 12),
  858 
  859         /* GPIO2A */
  860         RK_PINDRIVE(2, 0, 0x0090, 0, 2),
  861         RK_PINDRIVE(2, 0, 0x0090, 1, 4),
  862         RK_PINDRIVE(2, 0, 0x0090, 2, 8),
  863         RK_PINDRIVE(2, 0, 0x0090, 3, 12),
  864 
  865         /* GPIO2B */
  866         RK_PINDRIVE(2, 1, 0x0094, 0, 2),
  867         RK_PINDRIVE(2, 1, 0x0094, 1, 4),
  868         RK_PINDRIVE(2, 1, 0x0094, 2, 8),
  869         RK_PINDRIVE(2, 1, 0x0094, 3, 12),
  870 
  871         /* GPIO2C */
  872         RK_PINDRIVE(2, 2, 0x0098, 0, 2),
  873         RK_PINDRIVE(2, 2, 0x0098, 1, 4),
  874         RK_PINDRIVE(2, 2, 0x0098, 2, 8),
  875         RK_PINDRIVE(2, 2, 0x0098, 3, 12),
  876 
  877         /* GPIO2D */
  878         RK_PINDRIVE(2, 3, 0x009c, 0, 2),
  879         RK_PINDRIVE(2, 3, 0x009c, 1, 4),
  880         RK_PINDRIVE(2, 3, 0x009c, 2, 8),
  881         RK_PINDRIVE(2, 3, 0x009c, 3, 12),
  882 
  883         /* GPIO3A */
  884         RK_PINDRIVE(3, 0, 0x00a0, 0, 2),
  885         RK_PINDRIVE(3, 0, 0x00a0, 1, 4),
  886         RK_PINDRIVE(3, 0, 0x00a0, 2, 8),
  887         RK_PINDRIVE(3, 0, 0x00a0, 3, 12),
  888 
  889         /* GPIO3B */
  890         RK_PINDRIVE(3, 1, 0x00a4, 0, 2),
  891         RK_PINDRIVE(3, 1, 0x00a4, 1, 4),
  892         RK_PINDRIVE(3, 1, 0x00a4, 2, 8),
  893         RK_PINDRIVE(3, 1, 0x00a4, 3, 12),
  894 
  895         /* GPIO3C */
  896         RK_PINDRIVE(3, 2, 0x00a8, 0, 2),
  897         RK_PINDRIVE(3, 2, 0x00a8, 1, 4),
  898         RK_PINDRIVE(3, 2, 0x00a8, 2, 8),
  899         RK_PINDRIVE(3, 2, 0x00a8, 3, 12),
  900 
  901         /* GPIO3D */
  902         RK_PINDRIVE(3, 3, 0x00ac, 0, 2),
  903         RK_PINDRIVE(3, 3, 0x00ac, 1, 4),
  904         RK_PINDRIVE(3, 3, 0x00ac, 2, 8),
  905         RK_PINDRIVE(3, 3, 0x00ac, 3, 12),
  906 
  907         /* GPIO4A */
  908         RK_PINDRIVE(4, 0, 0x00b0, 0, 2),
  909         RK_PINDRIVE(4, 0, 0x00b0, 1, 4),
  910         RK_PINDRIVE(4, 0, 0x00b0, 2, 8),
  911         RK_PINDRIVE(4, 0, 0x00b0, 3, 12),
  912 
  913         /* GPIO4B */
  914         RK_PINDRIVE(4, 1, 0x00b4, 0, 2),
  915         RK_PINDRIVE(4, 1, 0x00b4, 1, 4),
  916         RK_PINDRIVE(4, 1, 0x00b4, 2, 8),
  917         RK_PINDRIVE(4, 1, 0x00b4, 3, 12),
  918 
  919         /* GPIO4C */
  920         RK_PINDRIVE(4, 2, 0x00b8, 0, 2),
  921         RK_PINDRIVE(4, 2, 0x00b8, 1, 4),
  922         RK_PINDRIVE(4, 2, 0x00b8, 2, 8),
  923         RK_PINDRIVE(4, 2, 0x00b8, 3, 12),
  924 
  925         /* GPIO4D */
  926         RK_PINDRIVE(4, 3, 0x00bc, 0, 2),
  927         RK_PINDRIVE(4, 3, 0x00bc, 1, 4),
  928         RK_PINDRIVE(4, 3, 0x00bc, 2, 8),
  929         RK_PINDRIVE(4, 3, 0x00bc, 3, 12),
  930 };
  931 
  932 static uint32_t
  933 rk3568_get_pd_offset(struct rk_pinctrl_softc *sc, uint32_t bank)
  934 {
  935 
  936         if (bank == 0)
  937                 return (0x20);
  938 
  939         /*
  940          * Registers start at 0x80, but bank index starts at 1. Return 0x70
  941          * so later calculations get the correct offset.
  942          */
  943         return (0x70);
  944 }
  945 
  946 static struct syscon *
  947 rk3568_get_syscon(struct rk_pinctrl_softc *sc, uint32_t bank)
  948 {
  949 
  950         if (bank)
  951                 return (sc->grf);
  952         else
  953                 return (sc->pmu);
  954 }
  955 
  956 static int
  957 rk3568_parse_bias(phandle_t node, int bank)
  958 {
  959 
  960         if (OF_hasprop(node, "bias-disable"))
  961                 return (0);
  962         if (OF_hasprop(node, "bias-pull-up"))
  963                 return (1);
  964         if (OF_hasprop(node, "bias-pull-down"))
  965                 return (2);
  966         return (-1);
  967 }
  968 
  969 static int
  970 rk3568_resolv_bias_value(int bank, int bias)
  971 {
  972 
  973         if (bias == 1)
  974                 return (GPIO_PIN_PULLUP);
  975         if (bias == 2)
  976                 return (GPIO_PIN_PULLDOWN);
  977         return (0);
  978 }
  979 
  980 static int
  981 rk3568_get_bias_value(int bank, int bias)
  982 {
  983 
  984         if (bias & GPIO_PIN_PULLUP)
  985                 return (1);
  986         if (bias & GPIO_PIN_PULLDOWN)
  987                 return (2);
  988         return (0);
  989 }
  990 
  991 struct rk_pinctrl_conf rk3568_conf = {
  992         .iomux_conf = rk3568_iomux_bank,
  993         .iomux_nbanks = nitems(rk3568_iomux_bank),
  994         .pin_fixup = rk3568_pin_fixup,
  995         .npin_fixup = nitems(rk3568_pin_fixup),
  996         .pin_drive = rk3568_pin_drive,
  997         .npin_drive = nitems(rk3568_pin_drive),
  998         .gpio_bank = rk3568_gpio_bank,
  999         .ngpio_bank = nitems(rk3568_gpio_bank),
 1000         .get_pd_offset = rk3568_get_pd_offset,
 1001         .get_syscon = rk3568_get_syscon,
 1002         .parse_bias = rk3568_parse_bias,
 1003         .resolv_bias_value = rk3568_resolv_bias_value,
 1004         .get_bias_value = rk3568_get_bias_value,
 1005 };
 1006 
 1007 static struct ofw_compat_data compat_data[] = {
 1008         {"rockchip,rk3288-pinctrl", (uintptr_t)&rk3288_conf},
 1009         {"rockchip,rk3328-pinctrl", (uintptr_t)&rk3328_conf},
 1010         {"rockchip,rk3399-pinctrl", (uintptr_t)&rk3399_conf},
 1011         {"rockchip,rk3568-pinctrl", (uintptr_t)&rk3568_conf},
 1012         {NULL,             0}
 1013 };
 1014 
 1015 static int
 1016 rk_pinctrl_parse_drive(struct rk_pinctrl_softc *sc, phandle_t node,
 1017   uint32_t bank, uint32_t subbank, uint32_t *drive, uint32_t *offset)
 1018 {
 1019         uint32_t value;
 1020         int i;
 1021 
 1022         if (OF_getencprop(node, "drive-strength", &value,
 1023             sizeof(value)) != 0)
 1024                 return (-1);
 1025 
 1026         /* Map to the correct drive value */
 1027         for (i = 0; i < sc->conf->npin_drive; i++) {
 1028                 if (sc->conf->pin_drive[i].bank != bank &&
 1029                     sc->conf->pin_drive[i].subbank != subbank)
 1030                         continue;
 1031                 if (sc->conf->pin_drive[i].ma == value) {
 1032                         *drive = sc->conf->pin_drive[i].value;
 1033                         return (0);
 1034                 }
 1035         }
 1036 
 1037         return (-1);
 1038 }
 1039 
 1040 static void
 1041 rk_pinctrl_get_fixup(struct rk_pinctrl_softc *sc, uint32_t bank, uint32_t pin,
 1042     uint32_t *reg, uint32_t *mask, uint32_t *bit)
 1043 {
 1044         int i;
 1045 
 1046         for (i = 0; i < sc->conf->npin_fixup; i++)
 1047                 if (sc->conf->pin_fixup[i].bank == bank &&
 1048                     sc->conf->pin_fixup[i].pin == pin) {
 1049                         *reg = sc->conf->pin_fixup[i].reg;
 1050                         *mask = sc->conf->pin_fixup[i].mask;
 1051                         *bit = sc->conf->pin_fixup[i].bit;
 1052 
 1053                         return;
 1054                 }
 1055 }
 1056 
 1057 static int
 1058 rk_pinctrl_handle_io(struct rk_pinctrl_softc *sc, phandle_t node, uint32_t bank,
 1059 uint32_t pin)
 1060 {
 1061         bool have_cfg, have_direction, have_value;
 1062         uint32_t  direction_value, pin_value;
 1063         struct rk_pinctrl_gpio *gpio;
 1064         int i, rv;
 1065 
 1066         have_cfg = false;
 1067         have_direction = false;
 1068         have_value = false;
 1069 
 1070         /* Get (subset of) GPIO pin properties. */
 1071         if (OF_hasprop(node, "output-disable")) {
 1072                 have_cfg = true;
 1073                 have_direction = true;
 1074                 direction_value = GPIO_PIN_INPUT;
 1075         }
 1076 
 1077         if (OF_hasprop(node, "output-enable")) {
 1078                 have_cfg = true;
 1079                 have_direction = true;
 1080                 direction_value = GPIO_PIN_OUTPUT;
 1081         }
 1082 
 1083         if (OF_hasprop(node, "output-low")) {
 1084                 have_cfg = true;
 1085                 have_direction = true;
 1086                 direction_value = GPIO_PIN_OUTPUT;
 1087                 have_value = true;
 1088                 pin_value = 0;
 1089         }
 1090 
 1091         if (OF_hasprop(node, "output-high")) {
 1092                 have_cfg = true;
 1093                 have_direction = true;
 1094                 direction_value = GPIO_PIN_OUTPUT;
 1095                 have_value = true;
 1096                 pin_value = 1;
 1097         }
 1098 
 1099         if (!have_cfg)
 1100                 return (0);
 1101 
 1102         /* Find gpio */
 1103         gpio = NULL;
 1104         for(i = 0; i < sc->conf->ngpio_bank; i++) {
 1105                 if (bank ==  sc->conf->gpio_bank[i].bank) {
 1106                         gpio = sc->conf->gpio_bank + i;
 1107                         break;
 1108                 }
 1109         }
 1110         if (gpio == NULL) {
 1111                 device_printf(sc->dev, "Cannot find GPIO bank %d\n", bank);
 1112                 return (ENXIO);
 1113         }
 1114         if (gpio->gpio_dev == NULL) {
 1115                 device_printf(sc->dev,
 1116                     "No GPIO subdevice found for bank %d\n", bank);
 1117                 return (ENXIO);
 1118         }
 1119 
 1120         rv = 0;
 1121         if (have_value) {
 1122                 rv = GPIO_PIN_SET(gpio->gpio_dev, pin, pin_value);
 1123                 if (rv != 0) {
 1124                         device_printf(sc->dev, "Cannot set GPIO value: %d\n",
 1125                             rv);
 1126                         return (rv);
 1127                 }
 1128         }
 1129 
 1130         if (have_direction) {
 1131                 rv = GPIO_PIN_SETFLAGS(gpio->gpio_dev, pin, direction_value);
 1132                 if (rv != 0) {
 1133                         device_printf(sc->dev,
 1134                             "Cannot set GPIO direction: %d\n", rv);
 1135                         return (rv);
 1136                 }
 1137         }
 1138 
 1139         return (0);
 1140 }
 1141 
 1142 static void
 1143 rk_pinctrl_configure_pin(struct rk_pinctrl_softc *sc, uint32_t *pindata)
 1144 {
 1145         phandle_t pin_conf;
 1146         struct syscon *syscon;
 1147         uint32_t bank, subbank, pin, function, bias;
 1148         uint32_t bit, mask, reg, drive;
 1149         int i, rv;
 1150 
 1151         bank = pindata[0];
 1152         pin = pindata[1];
 1153         function = pindata[2];
 1154         pin_conf = OF_node_from_xref(pindata[3]);
 1155         subbank = pin / 8;
 1156 
 1157         for (i = 0; i < sc->conf->iomux_nbanks; i++)
 1158                 if (sc->conf->iomux_conf[i].bank == bank &&
 1159                     sc->conf->iomux_conf[i].subbank == subbank)
 1160                         break;
 1161 
 1162         if (i == sc->conf->iomux_nbanks) {
 1163                 device_printf(sc->dev, "Unknown pin %d in bank %d\n", pin,
 1164                     bank);
 1165                 return;
 1166         }
 1167 
 1168         /* Find syscon */
 1169         syscon = sc->conf->get_syscon(sc, bank);
 1170 
 1171         /* Setup GPIO properties first */
 1172         rv = rk_pinctrl_handle_io(sc, pin_conf, bank, pin);
 1173 
 1174         /* Then pin pull-up/down */
 1175         bias = sc->conf->parse_bias(pin_conf, bank);
 1176         if (bias >= 0) {
 1177                 reg = sc->conf->get_pd_offset(sc, bank);
 1178                 reg += bank * 0x10 + ((pin / 8) * 0x4);
 1179                 bit = (pin % 8) * 2;
 1180                 mask = (0x3 << bit);
 1181                 SYSCON_MODIFY_4(syscon, reg, mask, bias << bit | (mask << 16));
 1182         }
 1183 
 1184         /* Then drive strength */
 1185         if (ofw_bus_node_is_compatible(ofw_bus_get_node(sc->dev),
 1186             "rockchip,rk3568-pinctrl")) {
 1187                 uint32_t value;
 1188                 if (OF_getencprop(pin_conf, "drive-strength", &value,
 1189                     sizeof(value)) == 0) {
 1190                         if (bank)
 1191                                 reg = 0x01c0 + (bank * 0x40) + (pin / 2 * 4);
 1192                         else
 1193                                 reg = 0x0070 + (pin / 2 * 4);
 1194 
 1195                         drive = ((1 << (value + 1)) - 1) << (pin % 2);
 1196 
 1197                         mask = 0x3f << (pin % 2);;
 1198 
 1199                         SYSCON_WRITE_4(syscon, reg, drive | (mask << 16));
 1200                 }
 1201         } else {
 1202                 rv = rk_pinctrl_parse_drive(sc, pin_conf, bank, subbank, &drive,
 1203                     &reg);
 1204                 if (rv == 0) {
 1205                         bit = (pin % 8) * 2;
 1206                         mask = (0x3 << bit);
 1207                         SYSCON_MODIFY_4(syscon, reg, mask,
 1208                             drive << bit | (mask << 16));
 1209                 }
 1210         }
 1211 
 1212         /* Finally set the pin function */
 1213         reg = sc->conf->iomux_conf[i].offset;
 1214         switch (sc->conf->iomux_conf[i].nbits) {
 1215         case 4:
 1216                 if ((pin % 8) >= 4)
 1217                         reg += 0x4;
 1218                 bit = (pin % 4) * 4;
 1219                 mask = (0xF << bit);
 1220                 break;
 1221         case 3:
 1222                 if ((pin % 8) >= 5)
 1223                         reg += 4;
 1224                 bit = (pin % 8 % 5) * 3;
 1225                 mask = (0x7 << bit);
 1226                 break;
 1227         case 2:
 1228                 bit = (pin % 8) * 2;
 1229                 mask = (0x3 << bit);
 1230                 break;
 1231         default:
 1232                 device_printf(sc->dev,
 1233                     "Unknown pin stride width %d in bank %d\n",
 1234                     sc->conf->iomux_conf[i].nbits, bank);
 1235                 return;
 1236         }
 1237         rk_pinctrl_get_fixup(sc, bank, pin, &reg, &mask, &bit);
 1238 
 1239         /*
 1240          * NOTE: not all syscon registers uses hi-word write mask, thus
 1241          * register modify method should be used.
 1242          * XXXX We should not pass write mask to syscon register 
 1243          * without hi-word write mask.
 1244          */
 1245         SYSCON_MODIFY_4(syscon, reg, mask, function << bit | (mask << 16));
 1246 
 1247         /* RK3568 specific pin mux for various functionalities */
 1248         if (ofw_bus_node_is_compatible(ofw_bus_get_node(sc->dev),
 1249             "rockchip,rk3568-pinctrl")) {
 1250                 if (bank == 3 && pin == 9 && function == 3)
 1251                         SYSCON_WRITE_4(sc->grf,
 1252                             GRF_IOFUNC_SEL0, GMAC1_IOMUX_SEL_M0);
 1253                 if (bank == 4 && pin == 7 && function == 3)
 1254                         SYSCON_WRITE_4(sc->grf,
 1255                             GRF_IOFUNC_SEL0, GMAC1_IOMUX_SEL_M1);
 1256         }
 1257 }
 1258 
 1259 static int
 1260 rk_pinctrl_configure_pins(device_t dev, phandle_t cfgxref)
 1261 {
 1262         struct rk_pinctrl_softc *sc;
 1263         phandle_t node;
 1264         uint32_t *pins;
 1265         int i, npins;
 1266 
 1267         sc = device_get_softc(dev);
 1268         node = OF_node_from_xref(cfgxref);
 1269 
 1270         npins = OF_getencprop_alloc_multi(node, "rockchip,pins",  sizeof(*pins),
 1271             (void **)&pins);
 1272         if (npins <= 0)
 1273                 return (ENOENT);
 1274 
 1275         for (i = 0; i != npins; i += 4)
 1276                 rk_pinctrl_configure_pin(sc, pins + i);
 1277 
 1278         return (0);
 1279 }
 1280 
 1281 static int
 1282 rk_pinctrl_is_gpio_locked(struct rk_pinctrl_softc *sc, struct syscon *syscon,
 1283   int bank, uint32_t pin, bool *is_gpio)
 1284 {
 1285         uint32_t subbank, bit, mask, reg;
 1286         uint32_t pinfunc;
 1287         int i;
 1288 
 1289         RK_PINCTRL_LOCK_ASSERT(sc);
 1290 
 1291         subbank = pin / 8;
 1292         *is_gpio = false;
 1293 
 1294         for (i = 0; i < sc->conf->iomux_nbanks; i++)
 1295                 if (sc->conf->iomux_conf[i].bank == bank &&
 1296                     sc->conf->iomux_conf[i].subbank == subbank)
 1297                         break;
 1298 
 1299         if (i == sc->conf->iomux_nbanks) {
 1300                 device_printf(sc->dev, "Unknown pin %d in bank %d\n", pin,
 1301                     bank);
 1302                 return (EINVAL);
 1303         }
 1304 
 1305         syscon = sc->conf->get_syscon(sc, bank);
 1306 
 1307         /* Parse pin function */
 1308         reg = sc->conf->iomux_conf[i].offset;
 1309         switch (sc->conf->iomux_conf[i].nbits) {
 1310         case 4:
 1311                 if ((pin % 8) >= 4)
 1312                         reg += 0x4;
 1313                 bit = (pin % 4) * 4;
 1314                 mask = (0xF << bit);
 1315                 break;
 1316         case 3:
 1317                 if ((pin % 8) >= 5)
 1318                         reg += 4;
 1319                 bit = (pin % 8 % 5) * 3;
 1320                 mask = (0x7 << bit);
 1321                 break;
 1322         case 2:
 1323                 bit = (pin % 8) * 2;
 1324                 mask = (0x3 << bit);
 1325                 break;
 1326         default:
 1327                 device_printf(sc->dev,
 1328                     "Unknown pin stride width %d in bank %d\n",
 1329                     sc->conf->iomux_conf[i].nbits, bank);
 1330                 return (EINVAL);
 1331         }
 1332         rk_pinctrl_get_fixup(sc, bank, pin, &reg, &mask, &bit);
 1333 
 1334         reg = SYSCON_READ_4(syscon, reg);
 1335         pinfunc = (reg & mask) >> bit;
 1336 
 1337         /* Test if the pin is in gpio mode */
 1338         if (pinfunc == 0)
 1339                 *is_gpio = true;
 1340 
 1341         return (0);
 1342 }
 1343 
 1344 static int
 1345 rk_pinctrl_get_bank(struct rk_pinctrl_softc *sc, device_t gpio, int *bank)
 1346 {
 1347         int i;
 1348 
 1349         for (i = 0; i < sc->conf->ngpio_bank; i++) {
 1350                 if (sc->conf->gpio_bank[i].gpio_dev == gpio)
 1351                         break;
 1352         }
 1353         if (i == sc->conf->ngpio_bank)
 1354                 return (EINVAL);
 1355 
 1356         *bank = i;
 1357         return (0);
 1358 }
 1359 
 1360 static int
 1361 rk_pinctrl_is_gpio(device_t pinctrl, device_t gpio, uint32_t pin, bool *is_gpio)
 1362 {
 1363         struct rk_pinctrl_softc *sc;
 1364         struct syscon *syscon;
 1365         int bank;
 1366         int rv;
 1367 
 1368         sc = device_get_softc(pinctrl);
 1369         RK_PINCTRL_LOCK(sc);
 1370 
 1371         rv = rk_pinctrl_get_bank(sc, gpio, &bank);
 1372         if (rv != 0)
 1373                 goto done;
 1374         syscon = sc->conf->get_syscon(sc, bank);
 1375         rv = rk_pinctrl_is_gpio_locked(sc, syscon, bank, pin, is_gpio);
 1376 
 1377 done:
 1378         RK_PINCTRL_UNLOCK(sc);
 1379 
 1380         return (rv);
 1381 }
 1382 
 1383 static int
 1384 rk_pinctrl_get_flags(device_t pinctrl, device_t gpio, uint32_t pin,
 1385     uint32_t *flags)
 1386 {
 1387         struct rk_pinctrl_softc *sc;
 1388         struct syscon *syscon;
 1389         uint32_t reg, bit;
 1390         uint32_t bias;
 1391         int bank;
 1392         int rv = 0;
 1393         bool is_gpio;
 1394 
 1395         sc = device_get_softc(pinctrl);
 1396         RK_PINCTRL_LOCK(sc);
 1397 
 1398         rv = rk_pinctrl_get_bank(sc, gpio, &bank);
 1399         if (rv != 0)
 1400                 goto done;
 1401         syscon = sc->conf->get_syscon(sc, bank);
 1402         rv = rk_pinctrl_is_gpio_locked(sc, syscon, bank, pin, &is_gpio);
 1403         if (rv != 0)
 1404                 goto done;
 1405         if (!is_gpio) {
 1406                 rv = EINVAL;
 1407                 goto done;
 1408         }
 1409         /* Get the pullup/pulldown configuration */
 1410         reg = sc->conf->get_pd_offset(sc, bank);
 1411         reg += bank * 0x10 + ((pin / 8) * 0x4);
 1412         bit = (pin % 8) * 2;
 1413         reg = SYSCON_READ_4(syscon, reg);
 1414         reg = (reg >> bit) & 0x3;
 1415         bias = sc->conf->resolv_bias_value(bank, reg);
 1416         *flags = bias;
 1417 
 1418 done:
 1419         RK_PINCTRL_UNLOCK(sc);
 1420         return (rv);
 1421 }
 1422 
 1423 static int
 1424 rk_pinctrl_set_flags(device_t pinctrl, device_t gpio, uint32_t pin,
 1425     uint32_t flags)
 1426 {
 1427         struct rk_pinctrl_softc *sc;
 1428         struct syscon *syscon;
 1429         uint32_t bit, mask, reg;
 1430         uint32_t bias;
 1431         int bank;
 1432         int rv = 0;
 1433         bool is_gpio;
 1434 
 1435         sc = device_get_softc(pinctrl);
 1436         RK_PINCTRL_LOCK(sc);
 1437 
 1438         rv = rk_pinctrl_get_bank(sc, gpio, &bank);
 1439         if (rv != 0)
 1440                 goto done;
 1441         syscon = sc->conf->get_syscon(sc, bank);
 1442         rv = rk_pinctrl_is_gpio_locked(sc, syscon, bank, pin, &is_gpio);
 1443         if (rv != 0)
 1444                 goto done;
 1445         if (!is_gpio) {
 1446                 rv = EINVAL;
 1447                 goto done;
 1448         }
 1449         /* Get the pullup/pulldown configuration */
 1450         reg = sc->conf->get_pd_offset(sc, bank);
 1451         reg += bank * 0x10 + ((pin / 8) * 0x4);
 1452         bit = (pin % 8) * 2;
 1453         mask = (0x3 << bit);
 1454         bias = sc->conf->get_bias_value(bank, flags);
 1455         SYSCON_MODIFY_4(syscon, reg, mask, bias << bit | (mask << 16));
 1456 
 1457 done:
 1458         RK_PINCTRL_UNLOCK(sc);
 1459         return (rv);
 1460 }
 1461 
 1462 static int
 1463 rk_pinctrl_probe(device_t dev)
 1464 {
 1465 
 1466         if (!ofw_bus_status_okay(dev))
 1467                 return (ENXIO);
 1468 
 1469         if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
 1470                 return (ENXIO);
 1471 
 1472         device_set_desc(dev, "RockChip Pinctrl controller");
 1473         return (BUS_PROBE_DEFAULT);
 1474 }
 1475 
 1476 static int
 1477 rk_pinctrl_attach(device_t dev)
 1478 {
 1479         struct rk_pinctrl_softc *sc;
 1480         phandle_t node;
 1481         device_t cdev;
 1482         int rv, gpio_unit;
 1483 
 1484         sc = device_get_softc(dev);
 1485         sc->dev = dev;
 1486 
 1487         node = ofw_bus_get_node(dev);
 1488 
 1489         if (OF_hasprop(node, "rockchip,grf") &&
 1490             syscon_get_by_ofw_property(dev, node,
 1491             "rockchip,grf", &sc->grf) != 0) {
 1492                 device_printf(dev, "cannot get grf driver handle\n");
 1493                 return (ENXIO);
 1494         }
 1495 
 1496         /* RK3568,RK3399,RK3288 have banks in PMU. RK3328 doesn't have a PMU. */
 1497         if (ofw_bus_node_is_compatible(node, "rockchip,rk3568-pinctrl") ||
 1498             ofw_bus_node_is_compatible(node, "rockchip,rk3399-pinctrl") ||
 1499             ofw_bus_node_is_compatible(node, "rockchip,rk3288-pinctrl")) {
 1500                 if (OF_hasprop(node, "rockchip,pmu") &&
 1501                     syscon_get_by_ofw_property(dev, node,
 1502                     "rockchip,pmu", &sc->pmu) != 0) {
 1503                         device_printf(dev, "cannot get pmu driver handle\n");
 1504                         return (ENXIO);
 1505                 }
 1506         }
 1507 
 1508         mtx_init(&sc->mtx, "rk pinctrl", "pinctrl", MTX_SPIN);
 1509 
 1510         sc->conf = (struct rk_pinctrl_conf *)ofw_bus_search_compatible(dev,
 1511             compat_data)->ocd_data;
 1512 
 1513         fdt_pinctrl_register(dev, "rockchip,pins");
 1514 
 1515         simplebus_init(dev, node);
 1516 
 1517         bus_generic_probe(dev);
 1518 
 1519         /* Attach child devices */
 1520         for (node = OF_child(node), gpio_unit = 0; node > 0;
 1521              node = OF_peer(node)) {
 1522                 if (!ofw_bus_node_is_compatible(node, "rockchip,gpio-bank"))
 1523                         continue;
 1524                 cdev = simplebus_add_device(dev, node, 0, NULL, -1, NULL);
 1525                 if (cdev == NULL) {
 1526                         device_printf(dev, " Cannot add GPIO subdevice\n");
 1527                         gpio_unit += 1;
 1528                         continue;
 1529                 }
 1530                 rv = device_probe_and_attach(cdev);
 1531                 if (rv != 0) {
 1532                         device_printf(sc->dev,
 1533                             "Cannot attach GPIO subdevice\n");
 1534                         gpio_unit += 1;
 1535                         continue;
 1536                 }
 1537                 sc->conf->gpio_bank[gpio_unit].gpio_dev = cdev;
 1538                 gpio_unit += 1;
 1539         }
 1540 
 1541         fdt_pinctrl_configure_tree(dev);
 1542 
 1543         return (bus_generic_attach(dev));
 1544 }
 1545 
 1546 static int
 1547 rk_pinctrl_detach(device_t dev)
 1548 {
 1549 
 1550         return (EBUSY);
 1551 }
 1552 
 1553 static device_method_t rk_pinctrl_methods[] = {
 1554         /* Device interface */
 1555         DEVMETHOD(device_probe,                 rk_pinctrl_probe),
 1556         DEVMETHOD(device_attach,                rk_pinctrl_attach),
 1557         DEVMETHOD(device_detach,                rk_pinctrl_detach),
 1558 
 1559         /* fdt_pinctrl interface */
 1560         DEVMETHOD(fdt_pinctrl_configure,        rk_pinctrl_configure_pins),
 1561         DEVMETHOD(fdt_pinctrl_is_gpio,          rk_pinctrl_is_gpio),
 1562         DEVMETHOD(fdt_pinctrl_get_flags,        rk_pinctrl_get_flags),
 1563         DEVMETHOD(fdt_pinctrl_set_flags,        rk_pinctrl_set_flags),
 1564 
 1565         DEVMETHOD_END
 1566 };
 1567 
 1568 DEFINE_CLASS_1(rk_pinctrl, rk_pinctrl_driver, rk_pinctrl_methods,
 1569     sizeof(struct rk_pinctrl_softc), simplebus_driver);
 1570 
 1571 EARLY_DRIVER_MODULE(rk_pinctrl, simplebus, rk_pinctrl_driver, 0, 0,
 1572     BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
 1573 MODULE_VERSION(rk_pinctrl, 1);

Cache object: d137df1f5d6ca58e439cb7b3e4b63c0b


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