linux/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Amlogic Meson6 and Meson8 DWMAC glue layer
   4 *
   5 * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
   6 */
   7
   8#include <linux/device.h>
   9#include <linux/ethtool.h>
  10#include <linux/io.h>
  11#include <linux/ioport.h>
  12#include <linux/module.h>
  13#include <linux/platform_device.h>
  14#include <linux/stmmac.h>
  15
  16#include "stmmac_platform.h"
  17
  18#define ETHMAC_SPEED_100        BIT(1)
  19
  20struct meson_dwmac {
  21        struct device   *dev;
  22        void __iomem    *reg;
  23};
  24
  25static void meson6_dwmac_fix_mac_speed(void *priv, unsigned int speed)
  26{
  27        struct meson_dwmac *dwmac = priv;
  28        unsigned int val;
  29
  30        val = readl(dwmac->reg);
  31
  32        switch (speed) {
  33        case SPEED_10:
  34                val &= ~ETHMAC_SPEED_100;
  35                break;
  36        case SPEED_100:
  37                val |= ETHMAC_SPEED_100;
  38                break;
  39        }
  40
  41        writel(val, dwmac->reg);
  42}
  43
  44static int meson6_dwmac_probe(struct platform_device *pdev)
  45{
  46        struct plat_stmmacenet_data *plat_dat;
  47        struct stmmac_resources stmmac_res;
  48        struct meson_dwmac *dwmac;
  49        struct resource *res;
  50        int ret;
  51
  52        ret = stmmac_get_platform_resources(pdev, &stmmac_res);
  53        if (ret)
  54                return ret;
  55
  56        plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
  57        if (IS_ERR(plat_dat))
  58                return PTR_ERR(plat_dat);
  59
  60        dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
  61        if (!dwmac) {
  62                ret = -ENOMEM;
  63                goto err_remove_config_dt;
  64        }
  65
  66        res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
  67        dwmac->reg = devm_ioremap_resource(&pdev->dev, res);
  68        if (IS_ERR(dwmac->reg)) {
  69                ret = PTR_ERR(dwmac->reg);
  70                goto err_remove_config_dt;
  71        }
  72
  73        plat_dat->bsp_priv = dwmac;
  74        plat_dat->fix_mac_speed = meson6_dwmac_fix_mac_speed;
  75
  76        ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
  77        if (ret)
  78                goto err_remove_config_dt;
  79
  80        return 0;
  81
  82err_remove_config_dt:
  83        stmmac_remove_config_dt(pdev, plat_dat);
  84
  85        return ret;
  86}
  87
  88static const struct of_device_id meson6_dwmac_match[] = {
  89        { .compatible = "amlogic,meson6-dwmac" },
  90        { }
  91};
  92MODULE_DEVICE_TABLE(of, meson6_dwmac_match);
  93
  94static struct platform_driver meson6_dwmac_driver = {
  95        .probe  = meson6_dwmac_probe,
  96        .remove = stmmac_pltfr_remove,
  97        .driver = {
  98                .name           = "meson6-dwmac",
  99                .pm             = &stmmac_pltfr_pm_ops,
 100                .of_match_table = meson6_dwmac_match,
 101        },
 102};
 103module_platform_driver(meson6_dwmac_driver);
 104
 105MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>");
 106MODULE_DESCRIPTION("Amlogic Meson6 and Meson8 DWMAC glue layer");
 107MODULE_LICENSE("GPL v2");
 108