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 20 struct meson_dwmac { 21 struct device *dev; 22 void __iomem *reg; 23 }; 24 25 static 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 44 static 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 82 err_remove_config_dt: 83 stmmac_remove_config_dt(pdev, plat_dat); 84 85 return ret; 86 } 87 88 static const struct of_device_id meson6_dwmac_match[] = { 89 { .compatible = "amlogic,meson6-dwmac" }, 90 { } 91 }; 92 MODULE_DEVICE_TABLE(of, meson6_dwmac_match); 93 94 static 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 }; 103 module_platform_driver(meson6_dwmac_driver); 104 105 MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>"); 106 MODULE_DESCRIPTION("Amlogic Meson6 and Meson8 DWMAC glue layer"); 107 MODULE_LICENSE("GPL v2"); 108