0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/device.h>
0009 #include <linux/ethtool.h>
0010 #include <linux/io.h>
0011 #include <linux/ioport.h>
0012 #include <linux/module.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/stmmac.h>
0015
0016 #include "stmmac_platform.h"
0017
0018 #define ETHMAC_SPEED_100 BIT(1)
0019
0020 struct meson_dwmac {
0021 struct device *dev;
0022 void __iomem *reg;
0023 };
0024
0025 static void meson6_dwmac_fix_mac_speed(void *priv, unsigned int speed)
0026 {
0027 struct meson_dwmac *dwmac = priv;
0028 unsigned int val;
0029
0030 val = readl(dwmac->reg);
0031
0032 switch (speed) {
0033 case SPEED_10:
0034 val &= ~ETHMAC_SPEED_100;
0035 break;
0036 case SPEED_100:
0037 val |= ETHMAC_SPEED_100;
0038 break;
0039 }
0040
0041 writel(val, dwmac->reg);
0042 }
0043
0044 static int meson6_dwmac_probe(struct platform_device *pdev)
0045 {
0046 struct plat_stmmacenet_data *plat_dat;
0047 struct stmmac_resources stmmac_res;
0048 struct meson_dwmac *dwmac;
0049 int ret;
0050
0051 ret = stmmac_get_platform_resources(pdev, &stmmac_res);
0052 if (ret)
0053 return ret;
0054
0055 plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
0056 if (IS_ERR(plat_dat))
0057 return PTR_ERR(plat_dat);
0058
0059 dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
0060 if (!dwmac) {
0061 ret = -ENOMEM;
0062 goto err_remove_config_dt;
0063 }
0064
0065 dwmac->reg = devm_platform_ioremap_resource(pdev, 1);
0066 if (IS_ERR(dwmac->reg)) {
0067 ret = PTR_ERR(dwmac->reg);
0068 goto err_remove_config_dt;
0069 }
0070
0071 plat_dat->bsp_priv = dwmac;
0072 plat_dat->fix_mac_speed = meson6_dwmac_fix_mac_speed;
0073
0074 ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
0075 if (ret)
0076 goto err_remove_config_dt;
0077
0078 return 0;
0079
0080 err_remove_config_dt:
0081 stmmac_remove_config_dt(pdev, plat_dat);
0082
0083 return ret;
0084 }
0085
0086 static const struct of_device_id meson6_dwmac_match[] = {
0087 { .compatible = "amlogic,meson6-dwmac" },
0088 { }
0089 };
0090 MODULE_DEVICE_TABLE(of, meson6_dwmac_match);
0091
0092 static struct platform_driver meson6_dwmac_driver = {
0093 .probe = meson6_dwmac_probe,
0094 .remove = stmmac_pltfr_remove,
0095 .driver = {
0096 .name = "meson6-dwmac",
0097 .pm = &stmmac_pltfr_pm_ops,
0098 .of_match_table = meson6_dwmac_match,
0099 },
0100 };
0101 module_platform_driver(meson6_dwmac_driver);
0102
0103 MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>");
0104 MODULE_DESCRIPTION("Amlogic Meson6 and Meson8 DWMAC glue layer");
0105 MODULE_LICENSE("GPL v2");