linux/drivers/net/ethernet/arc/emac_rockchip.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/**
   3 * emac-rockchip.c - Rockchip EMAC specific glue layer
   4 *
   5 * Copyright (C) 2014 Romain Perier <romain.perier@gmail.com>
   6 */
   7
   8#include <linux/etherdevice.h>
   9#include <linux/mfd/syscon.h>
  10#include <linux/module.h>
  11#include <linux/of_net.h>
  12#include <linux/platform_device.h>
  13#include <linux/regmap.h>
  14#include <linux/regulator/consumer.h>
  15
  16#include "emac.h"
  17
  18#define DRV_NAME        "rockchip_emac"
  19
  20struct emac_rockchip_soc_data {
  21        unsigned int grf_offset;
  22        unsigned int grf_mode_offset;
  23        unsigned int grf_speed_offset;
  24        bool need_div_macclk;
  25};
  26
  27struct rockchip_priv_data {
  28        struct arc_emac_priv emac;
  29        struct regmap *grf;
  30        const struct emac_rockchip_soc_data *soc_data;
  31        struct regulator *regulator;
  32        struct clk *refclk;
  33        struct clk *macclk;
  34};
  35
  36static void emac_rockchip_set_mac_speed(void *priv, unsigned int speed)
  37{
  38        struct rockchip_priv_data *emac = priv;
  39        u32 speed_offset = emac->soc_data->grf_speed_offset;
  40        u32 data;
  41        int err = 0;
  42
  43        switch (speed) {
  44        case 10:
  45                data = (1 << (speed_offset + 16)) | (0 << speed_offset);
  46                break;
  47        case 100:
  48                data = (1 << (speed_offset + 16)) | (1 << speed_offset);
  49                break;
  50        default:
  51                pr_err("speed %u not supported\n", speed);
  52                return;
  53        }
  54
  55        err = regmap_write(emac->grf, emac->soc_data->grf_offset, data);
  56        if (err)
  57                pr_err("unable to apply speed %u to grf (%d)\n", speed, err);
  58}
  59
  60static const struct emac_rockchip_soc_data emac_rk3036_emac_data = {
  61        .grf_offset = 0x140,   .grf_mode_offset = 8,
  62        .grf_speed_offset = 9, .need_div_macclk = 1,
  63};
  64
  65static const struct emac_rockchip_soc_data emac_rk3066_emac_data = {
  66        .grf_offset = 0x154,   .grf_mode_offset = 0,
  67        .grf_speed_offset = 1, .need_div_macclk = 0,
  68};
  69
  70static const struct emac_rockchip_soc_data emac_rk3188_emac_data = {
  71        .grf_offset = 0x0a4,   .grf_mode_offset = 0,
  72        .grf_speed_offset = 1, .need_div_macclk = 0,
  73};
  74
  75static const struct of_device_id emac_rockchip_dt_ids[] = {
  76        {
  77                .compatible = "rockchip,rk3036-emac",
  78                .data = &emac_rk3036_emac_data,
  79        },
  80        {
  81                .compatible = "rockchip,rk3066-emac",
  82                .data = &emac_rk3066_emac_data,
  83        },
  84        {
  85                .compatible = "rockchip,rk3188-emac",
  86                .data = &emac_rk3188_emac_data,
  87        },
  88        { /* Sentinel */ }
  89};
  90
  91MODULE_DEVICE_TABLE(of, emac_rockchip_dt_ids);
  92
  93static int emac_rockchip_probe(struct platform_device *pdev)
  94{
  95        struct device *dev = &pdev->dev;
  96        struct net_device *ndev;
  97        struct rockchip_priv_data *priv;
  98        const struct of_device_id *match;
  99        phy_interface_t interface;
 100        u32 data;
 101        int err;
 102
 103        if (!pdev->dev.of_node)
 104                return -ENODEV;
 105
 106        ndev = alloc_etherdev(sizeof(struct rockchip_priv_data));
 107        if (!ndev)
 108                return -ENOMEM;
 109        platform_set_drvdata(pdev, ndev);
 110        SET_NETDEV_DEV(ndev, dev);
 111
 112        priv = netdev_priv(ndev);
 113        priv->emac.drv_name = DRV_NAME;
 114        priv->emac.set_mac_speed = emac_rockchip_set_mac_speed;
 115
 116        err = of_get_phy_mode(dev->of_node, &interface);
 117        if (err)
 118                goto out_netdev;
 119
 120        /* RK3036/RK3066/RK3188 SoCs only support RMII */
 121        if (interface != PHY_INTERFACE_MODE_RMII) {
 122                dev_err(dev, "unsupported phy interface mode %d\n", interface);
 123                err = -ENOTSUPP;
 124                goto out_netdev;
 125        }
 126
 127        priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
 128                                                    "rockchip,grf");
 129        if (IS_ERR(priv->grf)) {
 130                dev_err(dev, "failed to retrieve global register file (%ld)\n",
 131                        PTR_ERR(priv->grf));
 132                err = PTR_ERR(priv->grf);
 133                goto out_netdev;
 134        }
 135
 136        match = of_match_node(emac_rockchip_dt_ids, dev->of_node);
 137        priv->soc_data = match->data;
 138
 139        priv->emac.clk = devm_clk_get(dev, "hclk");
 140        if (IS_ERR(priv->emac.clk)) {
 141                dev_err(dev, "failed to retrieve host clock (%ld)\n",
 142                        PTR_ERR(priv->emac.clk));
 143                err = PTR_ERR(priv->emac.clk);
 144                goto out_netdev;
 145        }
 146
 147        priv->refclk = devm_clk_get(dev, "macref");
 148        if (IS_ERR(priv->refclk)) {
 149                dev_err(dev, "failed to retrieve reference clock (%ld)\n",
 150                        PTR_ERR(priv->refclk));
 151                err = PTR_ERR(priv->refclk);
 152                goto out_netdev;
 153        }
 154
 155        err = clk_prepare_enable(priv->refclk);
 156        if (err) {
 157                dev_err(dev, "failed to enable reference clock (%d)\n", err);
 158                goto out_netdev;
 159        }
 160
 161        /* Optional regulator for PHY */
 162        priv->regulator = devm_regulator_get_optional(dev, "phy");
 163        if (IS_ERR(priv->regulator)) {
 164                if (PTR_ERR(priv->regulator) == -EPROBE_DEFER) {
 165                        err = -EPROBE_DEFER;
 166                        goto out_clk_disable;
 167                }
 168                dev_err(dev, "no regulator found\n");
 169                priv->regulator = NULL;
 170        }
 171
 172        if (priv->regulator) {
 173                err = regulator_enable(priv->regulator);
 174                if (err) {
 175                        dev_err(dev, "failed to enable phy-supply (%d)\n", err);
 176                        goto out_clk_disable;
 177                }
 178        }
 179
 180        /* Set speed 100M */
 181        data = (1 << (priv->soc_data->grf_speed_offset + 16)) |
 182               (1 << priv->soc_data->grf_speed_offset);
 183        /* Set RMII mode */
 184        data |= (1 << (priv->soc_data->grf_mode_offset + 16)) |
 185                (0 << priv->soc_data->grf_mode_offset);
 186
 187        err = regmap_write(priv->grf, priv->soc_data->grf_offset, data);
 188        if (err) {
 189                dev_err(dev, "unable to apply initial settings to grf (%d)\n",
 190                        err);
 191                goto out_regulator_disable;
 192        }
 193
 194        /* RMII interface needs always a rate of 50MHz */
 195        err = clk_set_rate(priv->refclk, 50000000);
 196        if (err) {
 197                dev_err(dev,
 198                        "failed to change reference clock rate (%d)\n", err);
 199                goto out_regulator_disable;
 200        }
 201
 202        if (priv->soc_data->need_div_macclk) {
 203                priv->macclk = devm_clk_get(dev, "macclk");
 204                if (IS_ERR(priv->macclk)) {
 205                        dev_err(dev, "failed to retrieve mac clock (%ld)\n",
 206                                PTR_ERR(priv->macclk));
 207                        err = PTR_ERR(priv->macclk);
 208                        goto out_regulator_disable;
 209                }
 210
 211                err = clk_prepare_enable(priv->macclk);
 212                if (err) {
 213                        dev_err(dev, "failed to enable mac clock (%d)\n", err);
 214                        goto out_regulator_disable;
 215                }
 216
 217                /* RMII TX/RX needs always a rate of 25MHz */
 218                err = clk_set_rate(priv->macclk, 25000000);
 219                if (err) {
 220                        dev_err(dev,
 221                                "failed to change mac clock rate (%d)\n", err);
 222                        goto out_clk_disable_macclk;
 223                }
 224        }
 225
 226        err = arc_emac_probe(ndev, interface);
 227        if (err) {
 228                dev_err(dev, "failed to probe arc emac (%d)\n", err);
 229                goto out_clk_disable_macclk;
 230        }
 231
 232        return 0;
 233
 234out_clk_disable_macclk:
 235        if (priv->soc_data->need_div_macclk)
 236                clk_disable_unprepare(priv->macclk);
 237out_regulator_disable:
 238        if (priv->regulator)
 239                regulator_disable(priv->regulator);
 240out_clk_disable:
 241        clk_disable_unprepare(priv->refclk);
 242out_netdev:
 243        free_netdev(ndev);
 244        return err;
 245}
 246
 247static int emac_rockchip_remove(struct platform_device *pdev)
 248{
 249        struct net_device *ndev = platform_get_drvdata(pdev);
 250        struct rockchip_priv_data *priv = netdev_priv(ndev);
 251        int err;
 252
 253        err = arc_emac_remove(ndev);
 254
 255        clk_disable_unprepare(priv->refclk);
 256
 257        if (priv->regulator)
 258                regulator_disable(priv->regulator);
 259
 260        if (priv->soc_data->need_div_macclk)
 261                clk_disable_unprepare(priv->macclk);
 262
 263        free_netdev(ndev);
 264        return err;
 265}
 266
 267static struct platform_driver emac_rockchip_driver = {
 268        .probe = emac_rockchip_probe,
 269        .remove = emac_rockchip_remove,
 270        .driver = {
 271                .name = DRV_NAME,
 272                .of_match_table  = emac_rockchip_dt_ids,
 273        },
 274};
 275
 276module_platform_driver(emac_rockchip_driver);
 277
 278MODULE_AUTHOR("Romain Perier <romain.perier@gmail.com>");
 279MODULE_DESCRIPTION("Rockchip EMAC platform driver");
 280MODULE_LICENSE("GPL");
 281