sunxi: initial 3.13 support
[15.05/openwrt.git] / target / linux / sunxi / patches-3.13 / 193-stmmac-platform-ext-for-a20.patch
1 From 3c6560eccfeee3a93d57c3b2206abfbe06459015 Mon Sep 17 00:00:00 2001
2 From: Chen-Yu Tsai <wens@csie.org>
3 Date: Sat, 7 Dec 2013 01:29:37 +0800
4 Subject: [PATCH] net: stmmac: sunxi platfrom extensions for GMAC in Allwinner
5  A20 SoC's
6
7 The Allwinner A20 has an ethernet controller that seems to be
8 an early version of Synopsys DesignWare MAC 10/100/1000 Universal,
9 which is supported by the stmmac driver.
10
11 Allwinner's GMAC requires setting additional registers in the SoC's
12 clock control unit.
13
14 The exact version of the DWMAC IP that Allwinner uses is unknown,
15 thus the exact feature set is unknown.
16
17 Signed-off-by: Chen-Yu Tsai <wens@csie.org>
18 ---
19  .../bindings/net/allwinner,sun7i-gmac.txt          | 22 +++++++
20  drivers/net/ethernet/stmicro/stmmac/Kconfig        | 12 ++++
21  drivers/net/ethernet/stmicro/stmmac/Makefile       |  1 +
22  drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c  | 76 ++++++++++++++++++++++
23  drivers/net/ethernet/stmicro/stmmac/stmmac.h       |  3 +
24  .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |  3 +
25  6 files changed, 117 insertions(+)
26  create mode 100644 Documentation/devicetree/bindings/net/allwinner,sun7i-gmac.txt
27  create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
28
29 diff --git a/Documentation/devicetree/bindings/net/allwinner,sun7i-gmac.txt b/Documentation/devicetree/bindings/net/allwinner,sun7i-gmac.txt
30 new file mode 100644
31 index 0000000..271554a
32 --- /dev/null
33 +++ b/Documentation/devicetree/bindings/net/allwinner,sun7i-gmac.txt
34 @@ -0,0 +1,22 @@
35 +* Allwinner GMAC ethernet controller
36 +
37 +This device is a platform glue layer for stmmac.
38 +Please see stmmac.txt for the other unchanged properties.
39 +
40 +Required properties:
41 + - compatible:  Should be "allwinner,sun7i-gmac"
42 + - reg: Address and length of register set for the device and corresponding
43 +   clock control
44 +
45 +Examples:
46 +
47 +       gmac: ethernet@01c50000 {
48 +               compatible = "allwinner,sun7i-gmac";
49 +               reg = <0x01c50000 0x10000>,
50 +                     <0x01c20164 0x4>;
51 +               interrupts = <0 85 1>;
52 +               interrupt-names = "macirq";
53 +               clocks = <&ahb_gates 49>;
54 +               clock-names = "stmmaceth";
55 +               phy-mode = "mii";
56 +       };
57 diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
58 index 6e52c0f..6d71210 100644
59 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
60 +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
61 @@ -25,6 +25,18 @@ config STMMAC_PLATFORM
62  
63           If unsure, say N.
64  
65 +config DWMAC_SUNXI
66 +       bool "Allwinner GMAC support"
67 +       depends on STMMAC_PLATFORM
68 +       depends on ARCH_SUNXI
69 +       default y
70 +       ---help---
71 +         Support for Allwinner A20 GMAC ethernet driver.
72 +
73 +         This selects Allwinner SoC glue layer support for the
74 +         stmmac device driver. This driver is used for A20 GMAC
75 +         ethernet controller.
76 +
77  config STMMAC_PCI
78         bool "STMMAC PCI bus support"
79         depends on STMMAC_ETH && PCI
80 diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
81 index 356a9dd..ecadece 100644
82 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile
83 +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
84 @@ -1,6 +1,7 @@
85  obj-$(CONFIG_STMMAC_ETH) += stmmac.o
86  stmmac-$(CONFIG_STMMAC_PLATFORM) += stmmac_platform.o
87  stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o
88 +stmmac-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o
89  stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \
90               chain_mode.o dwmac_lib.o dwmac1000_core.o  dwmac1000_dma.o \
91               dwmac100_core.o dwmac100_dma.o enh_desc.o  norm_desc.o \
92 diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
93 new file mode 100644
94 index 0000000..6c9fdb0
95 --- /dev/null
96 +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
97 @@ -0,0 +1,76 @@
98 +/**
99 + * dwmac-sunxi.c - Allwinner sunxi DWMAC specific glue layer
100 + *
101 + * Copyright (C) 2013 Chen-Yu Tsai
102 + *
103 + * Chen-Yu Tsai  <wens@csie.org>
104 + *
105 + * This program is free software; you can redistribute it and/or modify
106 + * it under the terms of the GNU General Public License as published by
107 + * the Free Software Foundation; either version 2 of the License, or
108 + * (at your option) any later version.
109 + *
110 + * This program is distributed in the hope that it will be useful,
111 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
112 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
113 + * GNU General Public License for more details.
114 + */
115 +
116 +#include <linux/clk.h>
117 +#include <linux/phy.h>
118 +#include <linux/stmmac.h>
119 +
120 +#define GMAC_IF_TYPE_RGMII     0x4
121 +
122 +#define GMAC_TX_CLK_MASK       0x3
123 +#define GMAC_TX_CLK_MII                0x0
124 +#define GMAC_TX_CLK_RGMII_INT  0x2
125 +
126 +static int sun7i_gmac_init(struct platform_device *pdev)
127 +{
128 +       struct resource *res;
129 +       struct device *dev = &pdev->dev;
130 +       void __iomem *addr = NULL;
131 +       struct plat_stmmacenet_data *plat_dat = NULL;
132 +       u32 priv_clk_reg;
133 +
134 +       plat_dat = dev_get_platdata(&pdev->dev);
135 +       if (!plat_dat)
136 +               return -EINVAL;
137 +
138 +       /* Get GMAC clock register in CCU */
139 +       res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
140 +       addr = devm_ioremap_resource(dev, res);
141 +       if (IS_ERR(addr))
142 +               return PTR_ERR(addr);
143 +
144 +       priv_clk_reg = readl(addr);
145 +
146 +       /* Set GMAC interface port mode */
147 +       if (plat_dat->interface == PHY_INTERFACE_MODE_RGMII)
148 +               priv_clk_reg |= GMAC_IF_TYPE_RGMII;
149 +       else
150 +               priv_clk_reg &= ~GMAC_IF_TYPE_RGMII;
151 +
152 +       /* Set GMAC transmit clock source. */
153 +       priv_clk_reg &= ~GMAC_TX_CLK_MASK;
154 +       if (plat_dat->interface == PHY_INTERFACE_MODE_RGMII
155 +                       || plat_dat->interface == PHY_INTERFACE_MODE_GMII)
156 +               priv_clk_reg |= GMAC_TX_CLK_RGMII_INT;
157 +       else
158 +               priv_clk_reg |= GMAC_TX_CLK_MII;
159 +
160 +       writel(priv_clk_reg, addr);
161 +
162 +       /* mask out phy addr 0x0 */
163 +       plat_dat->mdio_bus_data->phy_mask = 0x1;
164 +
165 +       return 0;
166 +}
167 +
168 +const struct plat_stmmacenet_data sun7i_gmac_data = {
169 +       .has_gmac = 1,
170 +       .tx_coe = 1,
171 +       .init = sun7i_gmac_init,
172 +};
173 +
174 diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
175 index 22f89ff..c8f659a 100644
176 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
177 +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
178 @@ -130,6 +130,9 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
179  bool stmmac_eee_init(struct stmmac_priv *priv);
180  
181  #ifdef CONFIG_STMMAC_PLATFORM
182 +#ifdef CONFIG_DWMAC_SUNXI
183 +extern const struct plat_stmmacenet_data sun7i_gmac_data;
184 +#endif
185  extern struct platform_driver stmmac_pltfr_driver;
186  static inline int stmmac_register_platform(void)
187  {
188 diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
189 index df3fd1c..6cf8292 100644
190 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
191 +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
192 @@ -35,6 +35,9 @@
193         { .compatible = "snps,dwmac-3.70a"},
194         { .compatible = "snps,dwmac-3.710"},
195         { .compatible = "snps,dwmac"},
196 +#ifdef CONFIG_DWMAC_SUNXI
197 +       { .compatible = "allwinner,sun7i-gmac", .data = &sun7i_gmac_data},
198 +#endif
199         { /* sentinel */ }
200  };
201  MODULE_DEVICE_TABLE(of, stmmac_dt_ids);
202 -- 
203 1.8.5.1
204