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, unsigned int mode) |
26 | { |
27 | struct meson_dwmac *dwmac = priv; |
28 | unsigned int val; |
29 | |
30 | val = readl(addr: 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, addr: 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 | int ret; |
50 | |
51 | ret = stmmac_get_platform_resources(pdev, stmmac_res: &stmmac_res); |
52 | if (ret) |
53 | return ret; |
54 | |
55 | plat_dat = devm_stmmac_probe_config_dt(pdev, mac: stmmac_res.mac); |
56 | if (IS_ERR(ptr: plat_dat)) |
57 | return PTR_ERR(ptr: plat_dat); |
58 | |
59 | dwmac = devm_kzalloc(dev: &pdev->dev, size: sizeof(*dwmac), GFP_KERNEL); |
60 | if (!dwmac) |
61 | return -ENOMEM; |
62 | |
63 | dwmac->reg = devm_platform_ioremap_resource(pdev, index: 1); |
64 | if (IS_ERR(ptr: dwmac->reg)) |
65 | return PTR_ERR(ptr: dwmac->reg); |
66 | |
67 | plat_dat->bsp_priv = dwmac; |
68 | plat_dat->fix_mac_speed = meson6_dwmac_fix_mac_speed; |
69 | |
70 | return stmmac_dvr_probe(device: &pdev->dev, plat_dat, res: &stmmac_res); |
71 | } |
72 | |
73 | static const struct of_device_id meson6_dwmac_match[] = { |
74 | { .compatible = "amlogic,meson6-dwmac" }, |
75 | { } |
76 | }; |
77 | MODULE_DEVICE_TABLE(of, meson6_dwmac_match); |
78 | |
79 | static struct platform_driver meson6_dwmac_driver = { |
80 | .probe = meson6_dwmac_probe, |
81 | .remove_new = stmmac_pltfr_remove, |
82 | .driver = { |
83 | .name = "meson6-dwmac" , |
84 | .pm = &stmmac_pltfr_pm_ops, |
85 | .of_match_table = meson6_dwmac_match, |
86 | }, |
87 | }; |
88 | module_platform_driver(meson6_dwmac_driver); |
89 | |
90 | MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>" ); |
91 | MODULE_DESCRIPTION("Amlogic Meson6 and Meson8 DWMAC glue layer" ); |
92 | MODULE_LICENSE("GPL v2" ); |
93 | |