1/*
2 * Amlogic Meson DWMAC glue layer
3 *
4 * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * You should have received a copy of the GNU General Public License
11 * along with this program. If not, see <http://www.gnu.org/licenses/>.
12 */
13
14#include <linux/device.h>
15#include <linux/ethtool.h>
16#include <linux/io.h>
17#include <linux/ioport.h>
18#include <linux/module.h>
19#include <linux/platform_device.h>
20#include <linux/stmmac.h>
21
22#include "stmmac_platform.h"
23
24#define ETHMAC_SPEED_100	BIT(1)
25
26struct meson_dwmac {
27	struct device	*dev;
28	void __iomem	*reg;
29};
30
31static void meson6_dwmac_fix_mac_speed(void *priv, unsigned int speed)
32{
33	struct meson_dwmac *dwmac = priv;
34	unsigned int val;
35
36	val = readl(dwmac->reg);
37
38	switch (speed) {
39	case SPEED_10:
40		val &= ~ETHMAC_SPEED_100;
41		break;
42	case SPEED_100:
43		val |= ETHMAC_SPEED_100;
44		break;
45	}
46
47	writel(val, dwmac->reg);
48}
49
50static int meson6_dwmac_probe(struct platform_device *pdev)
51{
52	struct plat_stmmacenet_data *plat_dat;
53	struct stmmac_resources stmmac_res;
54	struct meson_dwmac *dwmac;
55	struct resource *res;
56	int ret;
57
58	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
59	if (ret)
60		return ret;
61
62	plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
63	if (IS_ERR(plat_dat))
64		return PTR_ERR(plat_dat);
65
66	dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
67	if (!dwmac)
68		return -ENOMEM;
69
70	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
71	dwmac->reg = devm_ioremap_resource(&pdev->dev, res);
72	if (IS_ERR(dwmac->reg))
73		return PTR_ERR(dwmac->reg);
74
75	plat_dat->bsp_priv = dwmac;
76	plat_dat->fix_mac_speed = meson6_dwmac_fix_mac_speed;
77
78	return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
79}
80
81static const struct of_device_id meson6_dwmac_match[] = {
82	{ .compatible = "amlogic,meson6-dwmac" },
83	{ }
84};
85MODULE_DEVICE_TABLE(of, meson6_dwmac_match);
86
87static struct platform_driver meson6_dwmac_driver = {
88	.probe  = meson6_dwmac_probe,
89	.remove = stmmac_pltfr_remove,
90	.driver = {
91		.name           = "meson6-dwmac",
92		.pm		= &stmmac_pltfr_pm_ops,
93		.of_match_table = meson6_dwmac_match,
94	},
95};
96module_platform_driver(meson6_dwmac_driver);
97
98MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>");
99MODULE_DESCRIPTION("Amlogic Meson DWMAC glue layer");
100MODULE_LICENSE("GPL v2");
101