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/if_dwc_rk.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 #include <sys/cdefs.h>
   29 __FBSDID("$FreeBSD$");
   30 
   31 #include <sys/param.h>
   32 #include <sys/systm.h>
   33 #include <sys/bus.h>
   34 #include <sys/kernel.h>
   35 #include <sys/module.h>
   36 #include <sys/socket.h>
   37 
   38 #include <machine/bus.h>
   39 
   40 #include <net/if.h>
   41 #include <net/if_media.h>
   42 
   43 #include <dev/dwc/if_dwc.h>
   44 #include <dev/dwc/if_dwcvar.h>
   45 #include <dev/ofw/ofw_bus.h>
   46 #include <dev/ofw/ofw_bus_subr.h>
   47 
   48 #include <dev/extres/clk/clk.h>
   49 #include <dev/extres/hwreset/hwreset.h>
   50 #include <dev/extres/regulator/regulator.h>
   51 #include <dev/extres/syscon/syscon.h>
   52 
   53 #include "if_dwc_if.h"
   54 #include "syscon_if.h"
   55 
   56 #define RK3328_GRF_MAC_CON0             0x0900
   57 #define  MAC_CON0_GMAC2IO_TX_DL_CFG_MASK        0x7F
   58 #define  MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT       0
   59 #define  MAC_CON0_GMAC2IO_RX_DL_CFG_MASK        0x7F
   60 #define  MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT       7
   61 
   62 #define RK3328_GRF_MAC_CON1             0x0904
   63 #define  MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA    (1 << 0)
   64 #define  MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA    (1 << 1)
   65 #define  MAC_CON1_GMAC2IO_GMII_CLK_SEL_MASK     (3 << 11)
   66 #define  MAC_CON1_GMAC2IO_GMII_CLK_SEL_125      (0 << 11)
   67 #define  MAC_CON1_GMAC2IO_GMII_CLK_SEL_25       (3 << 11)
   68 #define  MAC_CON1_GMAC2IO_GMII_CLK_SEL_2_5      (2 << 11)
   69 #define  MAC_CON1_GMAC2IO_RMII_MODE_MASK        (1 << 9)
   70 #define  MAC_CON1_GMAC2IO_RMII_MODE             (1 << 9)
   71 #define  MAC_CON1_GMAC2IO_INTF_SEL_MASK         (7 << 4)
   72 #define  MAC_CON1_GMAC2IO_INTF_RMII             (4 << 4)
   73 #define  MAC_CON1_GMAC2IO_INTF_RGMII            (1 << 4)
   74 #define  MAC_CON1_GMAC2IO_RMII_CLK_SEL_MASK     (1 << 7)
   75 #define  MAC_CON1_GMAC2IO_RMII_CLK_SEL_25       (1 << 7)
   76 #define  MAC_CON1_GMAC2IO_RMII_CLK_SEL_2_5      (0 << 7)
   77 #define  MAC_CON1_GMAC2IO_MAC_SPEED_MASK        (1 << 2)
   78 #define  MAC_CON1_GMAC2IO_MAC_SPEED_100         (1 << 2)
   79 #define  MAC_CON1_GMAC2IO_MAC_SPEED_10          (0 << 2)
   80 #define RK3328_GRF_MAC_CON2             0x0908
   81 #define RK3328_GRF_MACPHY_CON0          0x0B00
   82 #define  MACPHY_CON0_CLK_50M_MASK               (1 << 14)
   83 #define  MACPHY_CON0_CLK_50M                    (1 << 14)
   84 #define  MACPHY_CON0_RMII_MODE_MASK             (3 << 6)
   85 #define  MACPHY_CON0_RMII_MODE                  (1 << 6)
   86 #define RK3328_GRF_MACPHY_CON1          0x0B04
   87 #define  MACPHY_CON1_RMII_MODE_MASK             (1 << 9)
   88 #define  MACPHY_CON1_RMII_MODE                  (1 << 9)
   89 #define RK3328_GRF_MACPHY_CON2          0x0B08
   90 #define RK3328_GRF_MACPHY_CON3          0x0B0C
   91 #define RK3328_GRF_MACPHY_STATUS        0x0B10
   92 
   93 #define RK3399_GRF_SOC_CON5             0xc214
   94 #define  SOC_CON5_GMAC_CLK_SEL_MASK             (3 << 4)
   95 #define  SOC_CON5_GMAC_CLK_SEL_125              (0 << 4)
   96 #define  SOC_CON5_GMAC_CLK_SEL_25               (3 << 4)
   97 #define  SOC_CON5_GMAC_CLK_SEL_2_5              (2 << 4)
   98 #define RK3399_GRF_SOC_CON6             0xc218
   99 #define  SOC_CON6_GMAC_TXCLK_DLY_ENA            (1 << 7)
  100 #define  SOC_CON6_TX_DL_CFG_MASK                0x7F
  101 #define  SOC_CON6_TX_DL_CFG_SHIFT               0
  102 #define  SOC_CON6_RX_DL_CFG_MASK                0x7F
  103 #define  SOC_CON6_GMAC_RXCLK_DLY_ENA            (1 << 15)
  104 #define  SOC_CON6_RX_DL_CFG_SHIFT               8
  105 
  106 struct if_dwc_rk_softc;
  107 
  108 typedef void (*if_dwc_rk_set_delaysfn_t)(struct if_dwc_rk_softc *);
  109 typedef int (*if_dwc_rk_set_speedfn_t)(struct if_dwc_rk_softc *, int);
  110 typedef void (*if_dwc_rk_set_phy_modefn_t)(struct if_dwc_rk_softc *);
  111 typedef void (*if_dwc_rk_phy_powerupfn_t)(struct if_dwc_rk_softc *);
  112 
  113 struct if_dwc_rk_ops {
  114         if_dwc_rk_set_delaysfn_t        set_delays;
  115         if_dwc_rk_set_speedfn_t         set_speed;
  116         if_dwc_rk_set_phy_modefn_t      set_phy_mode;
  117         if_dwc_rk_phy_powerupfn_t       phy_powerup;
  118 };
  119 
  120 struct if_dwc_rk_softc {
  121         struct dwc_softc        base;
  122         uint32_t                tx_delay;
  123         uint32_t                rx_delay;
  124         bool                    integrated_phy;
  125         bool                    clock_in;
  126         phandle_t               phy_node;
  127         struct syscon           *grf;
  128         struct if_dwc_rk_ops    *ops;
  129         /* Common clocks */
  130         clk_t                   mac_clk_rx;
  131         clk_t                   mac_clk_tx;
  132         clk_t                   aclk_mac;
  133         clk_t                   pclk_mac;
  134         clk_t                   clk_stmmaceth;
  135         /* RMII clocks */
  136         clk_t                   clk_mac_ref;
  137         clk_t                   clk_mac_refout;
  138         /* PHY clock */
  139         clk_t                   clk_phy;
  140 };
  141 
  142 static void rk3328_set_delays(struct if_dwc_rk_softc *sc);
  143 static int rk3328_set_speed(struct if_dwc_rk_softc *sc, int speed);
  144 static void rk3328_set_phy_mode(struct if_dwc_rk_softc *sc);
  145 static void rk3328_phy_powerup(struct if_dwc_rk_softc *sc);
  146 
  147 static void rk3399_set_delays(struct if_dwc_rk_softc *sc);
  148 static int rk3399_set_speed(struct if_dwc_rk_softc *sc, int speed);
  149 
  150 static struct if_dwc_rk_ops rk3288_ops = {
  151 };
  152 
  153 static struct if_dwc_rk_ops rk3328_ops = {
  154         .set_delays = rk3328_set_delays,
  155         .set_speed = rk3328_set_speed,
  156         .set_phy_mode = rk3328_set_phy_mode,
  157         .phy_powerup = rk3328_phy_powerup,
  158 };
  159 
  160 static struct if_dwc_rk_ops rk3399_ops = {
  161         .set_delays = rk3399_set_delays,
  162         .set_speed = rk3399_set_speed,
  163 };
  164 
  165 static struct ofw_compat_data compat_data[] = {
  166         {"rockchip,rk3288-gmac", (uintptr_t)&rk3288_ops},
  167         {"rockchip,rk3328-gmac", (uintptr_t)&rk3328_ops},
  168         {"rockchip,rk3399-gmac", (uintptr_t)&rk3399_ops},
  169         {NULL,                   0}
  170 };
  171 
  172 static void
  173 rk3328_set_delays(struct if_dwc_rk_softc *sc)
  174 {
  175         uint32_t reg;
  176         uint32_t tx, rx;
  177 
  178         if (sc->base.phy_mode != PHY_MODE_RGMII)
  179                 return;
  180 
  181         reg = SYSCON_READ_4(sc->grf, RK3328_GRF_MAC_CON0);
  182         tx = ((reg >> MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT) & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK);
  183         rx = ((reg >> MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT) & MAC_CON0_GMAC2IO_RX_DL_CFG_MASK);
  184 
  185         reg = SYSCON_READ_4(sc->grf, RK3328_GRF_MAC_CON1);
  186         if (bootverbose) {
  187                 device_printf(sc->base.dev, "current delays settings: tx=%u(%s) rx=%u(%s)\n",
  188                     tx, ((reg & MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA) ? "enabled" : "disabled"),
  189                     rx, ((reg & MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA) ? "enabled" : "disabled"));
  190 
  191                 device_printf(sc->base.dev, "setting new RK3328 RX/TX delays:  %d/%d\n",
  192                         sc->tx_delay, sc->rx_delay);
  193         }
  194 
  195         reg = (MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA | MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA) << 16;
  196         reg |= (MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA | MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA);
  197         SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1, reg);
  198 
  199         reg = 0xffff << 16;
  200         reg |= ((sc->tx_delay & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK) <<
  201             MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT);
  202         reg |= ((sc->rx_delay & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK) <<
  203             MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT);
  204         SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON0, reg);
  205 }
  206 
  207 static int
  208 rk3328_set_speed(struct if_dwc_rk_softc *sc, int speed)
  209 {
  210         uint32_t reg;
  211 
  212         switch (sc->base.phy_mode) {
  213         case PHY_MODE_RGMII:
  214                 switch (speed) {
  215                 case IFM_1000_T:
  216                 case IFM_1000_SX:
  217                         reg = MAC_CON1_GMAC2IO_GMII_CLK_SEL_125;
  218                         break;
  219                 case IFM_100_TX:
  220                         reg = MAC_CON1_GMAC2IO_GMII_CLK_SEL_25;
  221                         break;
  222                 case IFM_10_T:
  223                         reg = MAC_CON1_GMAC2IO_GMII_CLK_SEL_2_5;
  224                         break;
  225                 default:
  226                         device_printf(sc->base.dev, "unsupported RGMII media %u\n", speed);
  227                         return (-1);
  228                 }
  229 
  230                 SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1,
  231                     ((MAC_CON1_GMAC2IO_GMII_CLK_SEL_MASK << 16) | reg));
  232                 break;
  233         case PHY_MODE_RMII:
  234                 switch (speed) {
  235                 case IFM_100_TX:
  236                         reg = MAC_CON1_GMAC2IO_RMII_CLK_SEL_25 |
  237                             MAC_CON1_GMAC2IO_MAC_SPEED_100;
  238                         break;
  239                 case IFM_10_T:
  240                         reg = MAC_CON1_GMAC2IO_RMII_CLK_SEL_2_5 |
  241                             MAC_CON1_GMAC2IO_MAC_SPEED_10;
  242                         break;
  243                 default:
  244                         device_printf(sc->base.dev, "unsupported RMII media %u\n", speed);
  245                         return (-1);
  246                 }
  247 
  248                 SYSCON_WRITE_4(sc->grf,
  249                     sc->integrated_phy ? RK3328_GRF_MAC_CON2 : RK3328_GRF_MAC_CON1,
  250                     reg |
  251                     ((MAC_CON1_GMAC2IO_RMII_CLK_SEL_MASK | MAC_CON1_GMAC2IO_MAC_SPEED_MASK) << 16));
  252                 break;
  253         }
  254 
  255         return (0);
  256 }
  257 
  258 static void
  259 rk3328_set_phy_mode(struct if_dwc_rk_softc *sc)
  260 {
  261 
  262         switch (sc->base.phy_mode) {
  263         case PHY_MODE_RGMII:
  264                 SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1,
  265                     ((MAC_CON1_GMAC2IO_INTF_SEL_MASK | MAC_CON1_GMAC2IO_RMII_MODE_MASK) << 16) |
  266                     MAC_CON1_GMAC2IO_INTF_RGMII);
  267                 break;
  268         case PHY_MODE_RMII:
  269                 SYSCON_WRITE_4(sc->grf, sc->integrated_phy ? RK3328_GRF_MAC_CON2 : RK3328_GRF_MAC_CON1,
  270                     ((MAC_CON1_GMAC2IO_INTF_SEL_MASK | MAC_CON1_GMAC2IO_RMII_MODE_MASK) << 16) |
  271                     MAC_CON1_GMAC2IO_INTF_RMII | MAC_CON1_GMAC2IO_RMII_MODE);
  272                 break;
  273         }
  274 }
  275 
  276 static void
  277 rk3328_phy_powerup(struct if_dwc_rk_softc *sc)
  278 {
  279         SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON1,
  280             (MACPHY_CON1_RMII_MODE_MASK << 16) |
  281             MACPHY_CON1_RMII_MODE);
  282 }
  283 
  284 static void
  285 rk3399_set_delays(struct if_dwc_rk_softc *sc)
  286 {
  287         uint32_t reg, tx, rx;
  288 
  289         if (sc->base.phy_mode != PHY_MODE_RGMII)
  290                 return;
  291 
  292         reg = SYSCON_READ_4(sc->grf, RK3399_GRF_SOC_CON6);
  293         tx = ((reg >> SOC_CON6_TX_DL_CFG_SHIFT) & SOC_CON6_TX_DL_CFG_MASK);
  294         rx = ((reg >> SOC_CON6_RX_DL_CFG_SHIFT) & SOC_CON6_RX_DL_CFG_MASK);
  295 
  296         if (bootverbose) {
  297                 device_printf(sc->base.dev, "current delays settings: tx=%u(%s) rx=%u(%s)\n",
  298                     tx, ((reg & SOC_CON6_GMAC_TXCLK_DLY_ENA) ? "enabled" : "disabled"),
  299                     rx, ((reg & SOC_CON6_GMAC_RXCLK_DLY_ENA) ? "enabled" : "disabled"));
  300 
  301                 device_printf(sc->base.dev, "setting new RK3399 RX/TX delays:  %d/%d\n",
  302                     sc->rx_delay, sc->tx_delay);
  303         }
  304 
  305         reg = 0xFFFF << 16;
  306         reg |= ((sc->tx_delay & SOC_CON6_TX_DL_CFG_MASK) <<
  307             SOC_CON6_TX_DL_CFG_SHIFT);
  308         reg |= ((sc->rx_delay & SOC_CON6_RX_DL_CFG_MASK) <<
  309             SOC_CON6_RX_DL_CFG_SHIFT);
  310         reg |= SOC_CON6_GMAC_TXCLK_DLY_ENA | SOC_CON6_GMAC_RXCLK_DLY_ENA;
  311 
  312         SYSCON_WRITE_4(sc->grf, RK3399_GRF_SOC_CON6, reg);
  313 }
  314 
  315 static int
  316 rk3399_set_speed(struct if_dwc_rk_softc *sc, int speed)
  317 {
  318         uint32_t reg;
  319 
  320         switch (speed) {
  321         case IFM_1000_T:
  322         case IFM_1000_SX:
  323                 reg = SOC_CON5_GMAC_CLK_SEL_125;
  324                 break;
  325         case IFM_100_TX:
  326                 reg = SOC_CON5_GMAC_CLK_SEL_25;
  327                 break;
  328         case IFM_10_T:
  329                 reg = SOC_CON5_GMAC_CLK_SEL_2_5;
  330                 break;
  331         default:
  332                 device_printf(sc->base.dev, "unsupported media %u\n", speed);
  333                 return (-1);
  334         }
  335 
  336         SYSCON_WRITE_4(sc->grf, RK3399_GRF_SOC_CON5,
  337             ((SOC_CON5_GMAC_CLK_SEL_MASK << 16) | reg));
  338         return (0);
  339 }
  340 
  341 static int
  342 if_dwc_rk_sysctl_delays(SYSCTL_HANDLER_ARGS)
  343 {
  344         struct if_dwc_rk_softc *sc;
  345         int rv;
  346         uint32_t rxtx;
  347 
  348         sc = arg1;
  349         rxtx = ((sc->rx_delay << 8) | sc->tx_delay);
  350 
  351         rv = sysctl_handle_int(oidp, &rxtx, 0, req);
  352         if (rv != 0 || req->newptr == NULL)
  353                 return (rv);
  354         sc->tx_delay = rxtx & 0xff;
  355         sc->rx_delay = (rxtx >> 8) & 0xff;
  356 
  357         if (sc->ops->set_delays)
  358             sc->ops->set_delays(sc);
  359 
  360         return (0);
  361 }
  362 
  363 static int
  364 if_dwc_rk_init_sysctl(struct if_dwc_rk_softc *sc)
  365 {
  366         struct sysctl_oid *child;
  367         struct sysctl_ctx_list *ctx_list;
  368 
  369         ctx_list = device_get_sysctl_ctx(sc->base.dev);
  370         child = device_get_sysctl_tree(sc->base.dev);
  371         SYSCTL_ADD_PROC(ctx_list,
  372             SYSCTL_CHILDREN(child), OID_AUTO, "delays",
  373             CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, sc, 0,
  374             if_dwc_rk_sysctl_delays, "", "RGMII RX/TX delays: ((rx << 8) | tx)");
  375 
  376         return (0);
  377 }
  378 
  379 static int
  380 if_dwc_rk_probe(device_t dev)
  381 {
  382 
  383         if (!ofw_bus_status_okay(dev))
  384                 return (ENXIO);
  385         if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
  386                 return (ENXIO);
  387         device_set_desc(dev, "Rockchip Gigabit Ethernet Controller");
  388 
  389         return (BUS_PROBE_DEFAULT);
  390 }
  391 
  392 static int
  393 if_dwc_rk_init_clocks(device_t dev)
  394 {
  395         struct if_dwc_rk_softc *sc;
  396         int error;
  397 
  398         sc = device_get_softc(dev);
  399         error = clk_set_assigned(dev, ofw_bus_get_node(dev));
  400         if (error != 0) {
  401                 device_printf(dev, "clk_set_assigned failed\n");
  402                 return (error);
  403         }
  404 
  405         /* Enable clocks */
  406         error = clk_get_by_ofw_name(dev, 0, "stmmaceth", &sc->clk_stmmaceth);
  407         if (error != 0) {
  408                 device_printf(dev, "could not find clock stmmaceth\n");
  409                 return (error);
  410         }
  411 
  412         if (clk_get_by_ofw_name(dev, 0, "mac_clk_rx", &sc->mac_clk_rx) != 0) {
  413                 device_printf(sc->base.dev, "could not get mac_clk_rx clock\n");
  414                 sc->mac_clk_rx = NULL;
  415         }
  416 
  417         if (clk_get_by_ofw_name(dev, 0, "mac_clk_tx", &sc->mac_clk_tx) != 0) {
  418                 device_printf(sc->base.dev, "could not get mac_clk_tx clock\n");
  419                 sc->mac_clk_tx = NULL;
  420         }
  421 
  422         if (clk_get_by_ofw_name(dev, 0, "aclk_mac", &sc->aclk_mac) != 0) {
  423                 device_printf(sc->base.dev, "could not get aclk_mac clock\n");
  424                 sc->aclk_mac = NULL;
  425         }
  426 
  427         if (clk_get_by_ofw_name(dev, 0, "pclk_mac", &sc->pclk_mac) != 0) {
  428                 device_printf(sc->base.dev, "could not get pclk_mac clock\n");
  429                 sc->pclk_mac = NULL;
  430         }
  431 
  432         if (sc->base.phy_mode == PHY_MODE_RGMII) {
  433                 if (clk_get_by_ofw_name(dev, 0, "clk_mac_ref", &sc->clk_mac_ref) != 0) {
  434                         device_printf(sc->base.dev, "could not get clk_mac_ref clock\n");
  435                         sc->clk_mac_ref = NULL;
  436                 }
  437 
  438                 if (!sc->clock_in) {
  439                         if (clk_get_by_ofw_name(dev, 0, "clk_mac_refout", &sc->clk_mac_refout) != 0) {
  440                                 device_printf(sc->base.dev, "could not get clk_mac_refout clock\n");
  441                                 sc->clk_mac_refout = NULL;
  442                         }
  443 
  444                         clk_set_freq(sc->clk_stmmaceth, 50000000, 0);
  445                 }
  446         }
  447 
  448         if ((sc->phy_node != 0) && sc->integrated_phy) {
  449                 if (clk_get_by_ofw_index(dev, sc->phy_node, 0, &sc->clk_phy) != 0) {
  450                         device_printf(sc->base.dev, "could not get PHY clock\n");
  451                         sc->clk_phy = NULL;
  452                 }
  453 
  454                 if (sc->clk_phy) {
  455                         clk_set_freq(sc->clk_phy, 50000000, 0);
  456                 }
  457         }
  458 
  459         if (sc->base.phy_mode == PHY_MODE_RMII) {
  460                 if (sc->mac_clk_rx)
  461                         clk_enable(sc->mac_clk_rx);
  462                 if (sc->clk_mac_ref)
  463                         clk_enable(sc->clk_mac_ref);
  464                 if (sc->clk_mac_refout)
  465                         clk_enable(sc->clk_mac_refout);
  466         }
  467         if (sc->clk_phy)
  468                 clk_enable(sc->clk_phy);
  469         if (sc->aclk_mac)
  470                 clk_enable(sc->aclk_mac);
  471         if (sc->pclk_mac)
  472                 clk_enable(sc->pclk_mac);
  473         if (sc->mac_clk_tx)
  474                 clk_enable(sc->mac_clk_tx);
  475 
  476         DELAY(50);
  477 
  478         return (0);
  479 }
  480 
  481 static int
  482 if_dwc_rk_init(device_t dev)
  483 {
  484         struct if_dwc_rk_softc *sc;
  485         phandle_t node;
  486         uint32_t rx, tx;
  487         int err;
  488         pcell_t phy_handle;
  489         char *clock_in_out;
  490         hwreset_t phy_reset;
  491         regulator_t phy_supply;
  492 
  493         sc = device_get_softc(dev);
  494         node = ofw_bus_get_node(dev);
  495         sc->ops = (struct if_dwc_rk_ops *)ofw_bus_search_compatible(dev, compat_data)->ocd_data;
  496         if (OF_hasprop(node, "rockchip,grf") &&
  497             syscon_get_by_ofw_property(dev, node,
  498             "rockchip,grf", &sc->grf) != 0) {
  499                 device_printf(dev, "cannot get grf driver handle\n");
  500                 return (ENXIO);
  501         }
  502 
  503         if (OF_getencprop(node, "tx_delay", &tx, sizeof(tx)) <= 0)
  504                 tx = 0x30;
  505         if (OF_getencprop(node, "rx_delay", &rx, sizeof(rx)) <= 0)
  506                 rx = 0x10;
  507         sc->tx_delay = tx;
  508         sc->rx_delay = rx;
  509 
  510         sc->clock_in = true;
  511         if (OF_getprop_alloc(node, "clock_in_out", (void **)&clock_in_out)) {
  512                 if (strcmp(clock_in_out, "input") == 0)
  513                         sc->clock_in = true;
  514                 else
  515                         sc->clock_in = false;
  516                 OF_prop_free(clock_in_out);
  517         }
  518 
  519         if (OF_getencprop(node, "phy-handle", (void *)&phy_handle,
  520             sizeof(phy_handle)) > 0)
  521                 sc->phy_node = OF_node_from_xref(phy_handle);
  522 
  523         if (sc->phy_node)
  524                 sc->integrated_phy = OF_hasprop(sc->phy_node, "phy-is-integrated");
  525 
  526         if (sc->integrated_phy)
  527                 device_printf(sc->base.dev, "PHY is integrated\n");
  528 
  529         if_dwc_rk_init_clocks(dev);
  530 
  531         if (sc->ops->set_phy_mode)
  532             sc->ops->set_phy_mode(sc);
  533 
  534         if (sc->ops->set_delays)
  535             sc->ops->set_delays(sc);
  536 
  537         /*
  538          * this also sets delays if tunable is defined
  539          */
  540         err = if_dwc_rk_init_sysctl(sc);
  541         if (err != 0)
  542                 return (err);
  543 
  544         if (regulator_get_by_ofw_property(sc->base.dev, 0,
  545                             "phy-supply", &phy_supply) == 0) {
  546                 if (regulator_enable(phy_supply)) {
  547                         device_printf(sc->base.dev,
  548                             "cannot enable 'phy' regulator\n");
  549                 }
  550         }
  551         else
  552                 device_printf(sc->base.dev, "no phy-supply property\n");
  553 
  554         /* Power up */
  555         if (sc->integrated_phy) {
  556                 if (sc->ops->phy_powerup)
  557                         sc->ops->phy_powerup(sc);
  558 
  559                 SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON0,
  560                     (MACPHY_CON0_CLK_50M_MASK << 16) |
  561                     MACPHY_CON0_CLK_50M);
  562                 SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON0,
  563                     (MACPHY_CON0_RMII_MODE_MASK << 16) |
  564                     MACPHY_CON0_RMII_MODE);
  565                 SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON2, 0xffff1234);
  566                 SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON3, 0x003f0035);
  567 
  568                 if (hwreset_get_by_ofw_idx(dev, sc->phy_node, 0, &phy_reset)  == 0) {
  569                         hwreset_assert(phy_reset);
  570                         DELAY(20);
  571                         hwreset_deassert(phy_reset);
  572                         DELAY(20);
  573                 }
  574         }
  575 
  576         return (0);
  577 }
  578 
  579 static int
  580 if_dwc_rk_mac_type(device_t dev)
  581 {
  582 
  583         return (DWC_GMAC_NORMAL_DESC);
  584 }
  585 
  586 static int
  587 if_dwc_rk_mii_clk(device_t dev)
  588 {
  589 
  590         /* Should be calculated from the clock */
  591         return (GMAC_MII_CLK_150_250M_DIV102);
  592 }
  593 
  594 static int
  595 if_dwc_rk_set_speed(device_t dev, int speed)
  596 {
  597         struct if_dwc_rk_softc *sc;
  598 
  599         sc = device_get_softc(dev);
  600 
  601         if (sc->ops->set_speed)
  602             return sc->ops->set_speed(sc, speed);
  603 
  604         return (0);
  605 }
  606 
  607 static device_method_t if_dwc_rk_methods[] = {
  608         DEVMETHOD(device_probe,         if_dwc_rk_probe),
  609 
  610         DEVMETHOD(if_dwc_init,          if_dwc_rk_init),
  611         DEVMETHOD(if_dwc_mac_type,      if_dwc_rk_mac_type),
  612         DEVMETHOD(if_dwc_mii_clk,       if_dwc_rk_mii_clk),
  613         DEVMETHOD(if_dwc_set_speed,     if_dwc_rk_set_speed),
  614 
  615         DEVMETHOD_END
  616 };
  617 
  618 extern driver_t dwc_driver;
  619 
  620 DEFINE_CLASS_1(dwc, dwc_rk_driver, if_dwc_rk_methods,
  621     sizeof(struct if_dwc_rk_softc), dwc_driver);
  622 DRIVER_MODULE(dwc_rk, simplebus, dwc_rk_driver, 0, 0);
  623 MODULE_DEPEND(dwc_rk, dwc, 1, 1, 1);

Cache object: 830c047b64962700fb4595f6137afc39


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