aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDinh Nguyen <dinguyen@altera.com>2014-03-26 23:45:10 -0400
committerDavid S. Miller <davem@davemloft.net>2014-03-28 15:06:32 -0400
commit801d233b7302eeab94750427a623c10c044cb0ca (patch)
tree30762d1b0832ec386d2a2b9bdbea890ba1c82086
parentbfd2793c9559ae73ae021797f1d4b097c27f24be (diff)
net: stmmac: Add SOCFPGA glue driver
Like the STi and sunxi series SOCs, Altera's SOCFPGA also needs a glue layer on top of the Synopsys gmac IP. This patch adds the platform driver for the glue layer which configures the IP before the generic STMMAC driver takes over. Signed-off-by: Dinh Nguyen <dinguyen@altera.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/Kconfig10
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/Makefile1
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c130
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac.h3
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c3
5 files changed, 147 insertions, 0 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index f2d7c702c77f..2d09c116cbc8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -26,6 +26,16 @@ config STMMAC_PLATFORM
26 26
27 If unsure, say N. 27 If unsure, say N.
28 28
29config DWMAC_SOCFPGA
30 bool "SOCFPGA dwmac support"
31 depends on STMMAC_PLATFORM && MFD_SYSCON && (ARCH_SOCFPGA || COMPILE_TEST)
32 help
33 Support for ethernet controller on Altera SOCFPGA
34
35 This selects the Altera SOCFPGA SoC glue layer support
36 for the stmmac device driver. This driver is used for
37 arria5 and cyclone5 FPGA SoCs.
38
29config DWMAC_SUNXI 39config DWMAC_SUNXI
30 bool "Allwinner GMAC support" 40 bool "Allwinner GMAC support"
31 depends on STMMAC_PLATFORM && ARCH_SUNXI 41 depends on STMMAC_PLATFORM && ARCH_SUNXI
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index dcef28775dad..18695ebef7e4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -3,6 +3,7 @@ stmmac-$(CONFIG_STMMAC_PLATFORM) += stmmac_platform.o
3stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o 3stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o
4stmmac-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o 4stmmac-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o
5stmmac-$(CONFIG_DWMAC_STI) += dwmac-sti.o 5stmmac-$(CONFIG_DWMAC_STI) += dwmac-sti.o
6stmmac-$(CONFIG_DWMAC_SOCFPGA) += dwmac-socfpga.o
6stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \ 7stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \
7 chain_mode.o dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \ 8 chain_mode.o dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \
8 dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \ 9 dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
new file mode 100644
index 000000000000..fd8a217556a1
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -0,0 +1,130 @@
1/* Copyright Altera Corporation (C) 2014. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License, version 2,
5 * as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 *
15 * Adopted from dwmac-sti.c
16 */
17
18#include <linux/mfd/syscon.h>
19#include <linux/of.h>
20#include <linux/of_net.h>
21#include <linux/phy.h>
22#include <linux/regmap.h>
23#include <linux/stmmac.h>
24
25#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII 0x0
26#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII 0x1
27#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII 0x2
28#define SYSMGR_EMACGRP_CTRL_PHYSEL_WIDTH 2
29#define SYSMGR_EMACGRP_CTRL_PHYSEL_MASK 0x00000003
30
31struct socfpga_dwmac {
32 int interface;
33 u32 reg_offset;
34 u32 reg_shift;
35 struct device *dev;
36 struct regmap *sys_mgr_base_addr;
37};
38
39static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *dev)
40{
41 struct device_node *np = dev->of_node;
42 struct regmap *sys_mgr_base_addr;
43 u32 reg_offset, reg_shift;
44 int ret;
45
46 dwmac->interface = of_get_phy_mode(np);
47
48 sys_mgr_base_addr = syscon_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon");
49 if (IS_ERR(sys_mgr_base_addr)) {
50 dev_info(dev, "No sysmgr-syscon node found\n");
51 return PTR_ERR(sys_mgr_base_addr);
52 }
53
54 ret = of_property_read_u32_index(np, "altr,sysmgr-syscon", 1, &reg_offset);
55 if (ret) {
56 dev_info(dev, "Could not read reg_offset from sysmgr-syscon!\n");
57 return -EINVAL;
58 }
59
60 ret = of_property_read_u32_index(np, "altr,sysmgr-syscon", 2, &reg_shift);
61 if (ret) {
62 dev_info(dev, "Could not read reg_shift from sysmgr-syscon!\n");
63 return -EINVAL;
64 }
65
66 dwmac->reg_offset = reg_offset;
67 dwmac->reg_shift = reg_shift;
68 dwmac->sys_mgr_base_addr = sys_mgr_base_addr;
69 dwmac->dev = dev;
70
71 return 0;
72}
73
74static int socfpga_dwmac_setup(struct socfpga_dwmac *dwmac)
75{
76 struct regmap *sys_mgr_base_addr = dwmac->sys_mgr_base_addr;
77 int phymode = dwmac->interface;
78 u32 reg_offset = dwmac->reg_offset;
79 u32 reg_shift = dwmac->reg_shift;
80 u32 ctrl, val;
81
82 switch (phymode) {
83 case PHY_INTERFACE_MODE_RGMII:
84 val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII;
85 break;
86 case PHY_INTERFACE_MODE_MII:
87 case PHY_INTERFACE_MODE_GMII:
88 val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
89 break;
90 default:
91 dev_err(dwmac->dev, "bad phy mode %d\n", phymode);
92 return -EINVAL;
93 }
94
95 regmap_read(sys_mgr_base_addr, reg_offset, &ctrl);
96 ctrl &= ~(SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << reg_shift);
97 ctrl |= val << reg_shift;
98
99 regmap_write(sys_mgr_base_addr, reg_offset, ctrl);
100 return 0;
101}
102
103static void *socfpga_dwmac_probe(struct platform_device *pdev)
104{
105 struct device *dev = &pdev->dev;
106 int ret;
107 struct socfpga_dwmac *dwmac;
108
109 dwmac = devm_kzalloc(dev, sizeof(*dwmac), GFP_KERNEL);
110 if (!dwmac)
111 return ERR_PTR(-ENOMEM);
112
113 ret = socfpga_dwmac_parse_data(dwmac, dev);
114 if (ret) {
115 dev_err(dev, "Unable to parse OF data\n");
116 return ERR_PTR(ret);
117 }
118
119 ret = socfpga_dwmac_setup(dwmac);
120 if (ret) {
121 dev_err(dev, "couldn't setup SoC glue (%d)\n", ret);
122 return ERR_PTR(ret);
123 }
124
125 return dwmac;
126}
127
128const struct stmmac_of_data socfpga_gmac_data = {
129 .setup = socfpga_dwmac_probe,
130};
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index f9e60d7918c4..ca01035634a7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -136,6 +136,9 @@ extern const struct stmmac_of_data sun7i_gmac_data;
136#ifdef CONFIG_DWMAC_STI 136#ifdef CONFIG_DWMAC_STI
137extern const struct stmmac_of_data sti_gmac_data; 137extern const struct stmmac_of_data sti_gmac_data;
138#endif 138#endif
139#ifdef CONFIG_DWMAC_SOCFPGA
140extern const struct stmmac_of_data socfpga_gmac_data;
141#endif
139extern struct platform_driver stmmac_pltfr_driver; 142extern struct platform_driver stmmac_pltfr_driver;
140static inline int stmmac_register_platform(void) 143static inline int stmmac_register_platform(void)
141{ 144{
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 8fb32a80f1c1..46aef5108bea 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -38,6 +38,9 @@ static const struct of_device_id stmmac_dt_ids[] = {
38 { .compatible = "st,stih416-dwmac", .data = &sti_gmac_data}, 38 { .compatible = "st,stih416-dwmac", .data = &sti_gmac_data},
39 { .compatible = "st,stid127-dwmac", .data = &sti_gmac_data}, 39 { .compatible = "st,stid127-dwmac", .data = &sti_gmac_data},
40#endif 40#endif
41#ifdef CONFIG_DWMAC_SOCFPGA
42 { .compatible = "altr,socfpga-stmmac", .data = &socfpga_gmac_data },
43#endif
41 /* SoC specific glue layers should come before generic bindings */ 44 /* SoC specific glue layers should come before generic bindings */
42 { .compatible = "st,spear600-gmac"}, 45 { .compatible = "st,spear600-gmac"},
43 { .compatible = "snps,dwmac-3.610"}, 46 { .compatible = "snps,dwmac-3.610"},