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 int meson6_dwmac_set_clk_tx_rate(void *bsp_priv, struct clk *clk_tx_i, 26 phy_interface_t interface, int speed) 27 { 28 struct meson_dwmac *dwmac = bsp_priv; 29 unsigned int val; 30 31 val = readl(dwmac->reg); 32 33 switch (speed) { 34 case SPEED_10: 35 val &= ~ETHMAC_SPEED_100; 36 break; 37 case SPEED_100: 38 val |= ETHMAC_SPEED_100; 39 break; 40 } 41 42 writel(val, dwmac->reg); 43 44 return 0; 45 } 46 47 static int meson6_dwmac_probe(struct platform_device *pdev) 48 { 49 struct plat_stmmacenet_data *plat_dat; 50 struct stmmac_resources stmmac_res; 51 struct meson_dwmac *dwmac; 52 int ret; 53 54 ret = stmmac_get_platform_resources(pdev, &stmmac_res); 55 if (ret) 56 return ret; 57 58 plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac); 59 if (IS_ERR(plat_dat)) 60 return PTR_ERR(plat_dat); 61 62 dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL); 63 if (!dwmac) 64 return -ENOMEM; 65 66 dwmac->reg = devm_platform_ioremap_resource(pdev, 1); 67 if (IS_ERR(dwmac->reg)) 68 return PTR_ERR(dwmac->reg); 69 70 plat_dat->bsp_priv = dwmac; 71 plat_dat->set_clk_tx_rate = meson6_dwmac_set_clk_tx_rate; 72 73 return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); 74 } 75 76 static const struct of_device_id meson6_dwmac_match[] = { 77 { .compatible = "amlogic,meson6-dwmac" }, 78 { } 79 }; 80 MODULE_DEVICE_TABLE(of, meson6_dwmac_match); 81 82 static struct platform_driver meson6_dwmac_driver = { 83 .probe = meson6_dwmac_probe, 84 .remove = stmmac_pltfr_remove, 85 .driver = { 86 .name = "meson6-dwmac", 87 .pm = &stmmac_pltfr_pm_ops, 88 .of_match_table = meson6_dwmac_match, 89 }, 90 }; 91 module_platform_driver(meson6_dwmac_driver); 92 93 MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>"); 94 MODULE_DESCRIPTION("Amlogic Meson6 and Meson8 DWMAC glue layer"); 95 MODULE_LICENSE("GPL v2"); 96