ipq806x: update stmmac to the version from linux 4.3
[openwrt/staging/yousong.git] / target / linux / ipq806x / patches-4.1 / 701-stmmac_update_to_4.3.patch
1 --- a/drivers/net/ethernet/stmicro/Kconfig
2 +++ b/drivers/net/ethernet/stmicro/Kconfig
3 @@ -7,9 +7,7 @@ config NET_VENDOR_STMICRO
4 default y
5 depends on HAS_IOMEM
6 ---help---
7 - If you have a network (Ethernet) card belonging to this class, say Y
8 - and read the Ethernet-HOWTO, available from
9 - <http://www.tldp.org/docs.html#howto>.
10 + If you have a network (Ethernet) card belonging to this class, say Y.
11
12 Note that the answer to this question doesn't directly affect the
13 kernel: saying N will just cause the configurator to skip all
14 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
15 +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
16 @@ -16,6 +16,7 @@ if STMMAC_ETH
17 config STMMAC_PLATFORM
18 tristate "STMMAC Platform bus support"
19 depends on STMMAC_ETH
20 + select MFD_SYSCON
21 default y
22 ---help---
23 This selects the platform specific bus support for the stmmac driver.
24 @@ -26,6 +27,95 @@ config STMMAC_PLATFORM
25
26 If unsure, say N.
27
28 +if STMMAC_PLATFORM
29 +
30 +config DWMAC_GENERIC
31 + tristate "Generic driver for DWMAC"
32 + default STMMAC_PLATFORM
33 + ---help---
34 + Generic DWMAC driver for platforms that don't require any
35 + platform specific code to function or is using platform
36 + data for setup.
37 +
38 +config DWMAC_IPQ806X
39 + tristate "QCA IPQ806x DWMAC support"
40 + default ARCH_QCOM
41 + depends on OF
42 + select MFD_SYSCON
43 + help
44 + Support for QCA IPQ806X DWMAC Ethernet.
45 +
46 + This selects the IPQ806x SoC glue layer support for the stmmac
47 + device driver. This driver does not use any of the hardware
48 + acceleration features available on this SoC. Network devices
49 + will behave like standard non-accelerated ethernet interfaces.
50 +
51 +config DWMAC_LPC18XX
52 + tristate "NXP LPC18xx/43xx DWMAC support"
53 + default ARCH_LPC18XX
54 + depends on OF
55 + select MFD_SYSCON
56 + ---help---
57 + Support for NXP LPC18xx/43xx DWMAC Ethernet.
58 +
59 +config DWMAC_MESON
60 + tristate "Amlogic Meson dwmac support"
61 + default ARCH_MESON
62 + depends on OF
63 + help
64 + Support for Ethernet controller on Amlogic Meson SoCs.
65 +
66 + This selects the Amlogic Meson SoC glue layer support for
67 + the stmmac device driver. This driver is used for Meson6 and
68 + Meson8 SoCs.
69 +
70 +config DWMAC_ROCKCHIP
71 + tristate "Rockchip dwmac support"
72 + default ARCH_ROCKCHIP
73 + depends on OF
74 + select MFD_SYSCON
75 + help
76 + Support for Ethernet controller on Rockchip RK3288 SoC.
77 +
78 + This selects the Rockchip RK3288 SoC glue layer support for
79 + the stmmac device driver.
80 +
81 +config DWMAC_SOCFPGA
82 + tristate "SOCFPGA dwmac support"
83 + default ARCH_SOCFPGA
84 + depends on OF
85 + select MFD_SYSCON
86 + help
87 + Support for ethernet controller on Altera SOCFPGA
88 +
89 + This selects the Altera SOCFPGA SoC glue layer support
90 + for the stmmac device driver. This driver is used for
91 + arria5 and cyclone5 FPGA SoCs.
92 +
93 +config DWMAC_STI
94 + tristate "STi GMAC support"
95 + default ARCH_STI
96 + depends on OF
97 + select MFD_SYSCON
98 + ---help---
99 + Support for ethernet controller on STi SOCs.
100 +
101 + This selects STi SoC glue layer support for the stmmac
102 + device driver. This driver is used on for the STi series
103 + SOCs GMAC ethernet controller.
104 +
105 +config DWMAC_SUNXI
106 + tristate "Allwinner GMAC support"
107 + default ARCH_SUNXI
108 + depends on OF
109 + ---help---
110 + Support for Allwinner A20/A31 GMAC ethernet controllers.
111 +
112 + This selects Allwinner SoC glue layer support for the
113 + stmmac device driver. This driver is used for A20/A31
114 + GMAC ethernet controller.
115 +endif
116 +
117 config STMMAC_PCI
118 tristate "STMMAC PCI bus support"
119 depends on STMMAC_ETH && PCI
120 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile
121 +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
122 @@ -4,9 +4,17 @@ stmmac-objs:= stmmac_main.o stmmac_ethto
123 dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
124 mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o $(stmmac-y)
125
126 -obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o
127 -stmmac-platform-objs:= stmmac_platform.o dwmac-meson.o dwmac-sunxi.o \
128 - dwmac-sti.o dwmac-socfpga.o dwmac-rk.o
129 +# Ordering matters. Generic driver must be last.
130 +obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o
131 +obj-$(CONFIG_DWMAC_IPQ806X) += dwmac-ipq806x.o
132 +obj-$(CONFIG_DWMAC_LPC18XX) += dwmac-lpc18xx.o
133 +obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o
134 +obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o
135 +obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-socfpga.o
136 +obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o
137 +obj-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o
138 +obj-$(CONFIG_DWMAC_GENERIC) += dwmac-generic.o
139 +stmmac-platform-objs:= stmmac_platform.o
140
141 obj-$(CONFIG_STMMAC_PCI) += stmmac-pci.o
142 stmmac-pci-objs:= stmmac_pci.o
143 --- /dev/null
144 +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
145 @@ -0,0 +1,81 @@
146 +/*
147 + * Generic DWMAC platform driver
148 + *
149 + * Copyright (C) 2007-2011 STMicroelectronics Ltd
150 + * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
151 + *
152 + * This file is licensed under the terms of the GNU General Public
153 + * License version 2. This program is licensed "as is" without any
154 + * warranty of any kind, whether express or implied.
155 + */
156 +
157 +#include <linux/module.h>
158 +#include <linux/of.h>
159 +#include <linux/platform_device.h>
160 +
161 +#include "stmmac.h"
162 +#include "stmmac_platform.h"
163 +
164 +static int dwmac_generic_probe(struct platform_device *pdev)
165 +{
166 + struct plat_stmmacenet_data *plat_dat;
167 + struct stmmac_resources stmmac_res;
168 + int ret;
169 +
170 + ret = stmmac_get_platform_resources(pdev, &stmmac_res);
171 + if (ret)
172 + return ret;
173 +
174 + if (pdev->dev.of_node) {
175 + plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
176 + if (IS_ERR(plat_dat)) {
177 + dev_err(&pdev->dev, "dt configuration failed\n");
178 + return PTR_ERR(plat_dat);
179 + }
180 + } else {
181 + plat_dat = dev_get_platdata(&pdev->dev);
182 + if (!plat_dat) {
183 + dev_err(&pdev->dev, "no platform data provided\n");
184 + return -EINVAL;
185 + }
186 +
187 + /* Set default value for multicast hash bins */
188 + plat_dat->multicast_filter_bins = HASH_TABLE_SIZE;
189 +
190 + /* Set default value for unicast filter entries */
191 + plat_dat->unicast_filter_entries = 1;
192 + }
193 +
194 + /* Custom initialisation (if needed) */
195 + if (plat_dat->init) {
196 + ret = plat_dat->init(pdev, plat_dat->bsp_priv);
197 + if (ret)
198 + return ret;
199 + }
200 +
201 + return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
202 +}
203 +
204 +static const struct of_device_id dwmac_generic_match[] = {
205 + { .compatible = "st,spear600-gmac"},
206 + { .compatible = "snps,dwmac-3.610"},
207 + { .compatible = "snps,dwmac-3.70a"},
208 + { .compatible = "snps,dwmac-3.710"},
209 + { .compatible = "snps,dwmac"},
210 + { }
211 +};
212 +MODULE_DEVICE_TABLE(of, dwmac_generic_match);
213 +
214 +static struct platform_driver dwmac_generic_driver = {
215 + .probe = dwmac_generic_probe,
216 + .remove = stmmac_pltfr_remove,
217 + .driver = {
218 + .name = STMMAC_RESOURCE_NAME,
219 + .pm = &stmmac_pltfr_pm_ops,
220 + .of_match_table = of_match_ptr(dwmac_generic_match),
221 + },
222 +};
223 +module_platform_driver(dwmac_generic_driver);
224 +
225 +MODULE_DESCRIPTION("Generic dwmac driver");
226 +MODULE_LICENSE("GPL v2");
227 --- /dev/null
228 +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
229 @@ -0,0 +1,373 @@
230 +/*
231 + * Qualcomm Atheros IPQ806x GMAC glue layer
232 + *
233 + * Copyright (C) 2015 The Linux Foundation
234 + *
235 + * Permission to use, copy, modify, and/or distribute this software for any
236 + * purpose with or without fee is hereby granted, provided that the above
237 + * copyright notice and this permission notice appear in all copies.
238 + *
239 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
240 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
241 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
242 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
243 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
244 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
245 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
246 + */
247 +
248 +#include <linux/device.h>
249 +#include <linux/platform_device.h>
250 +#include <linux/phy.h>
251 +#include <linux/regmap.h>
252 +#include <linux/clk.h>
253 +#include <linux/reset.h>
254 +#include <linux/of_net.h>
255 +#include <linux/mfd/syscon.h>
256 +#include <linux/stmmac.h>
257 +#include <linux/of_mdio.h>
258 +#include <linux/module.h>
259 +
260 +#include "stmmac_platform.h"
261 +
262 +#define NSS_COMMON_CLK_GATE 0x8
263 +#define NSS_COMMON_CLK_GATE_PTP_EN(x) BIT(0x10 + x)
264 +#define NSS_COMMON_CLK_GATE_RGMII_RX_EN(x) BIT(0x9 + (x * 2))
265 +#define NSS_COMMON_CLK_GATE_RGMII_TX_EN(x) BIT(0x8 + (x * 2))
266 +#define NSS_COMMON_CLK_GATE_GMII_RX_EN(x) BIT(0x4 + x)
267 +#define NSS_COMMON_CLK_GATE_GMII_TX_EN(x) BIT(0x0 + x)
268 +
269 +#define NSS_COMMON_CLK_DIV0 0xC
270 +#define NSS_COMMON_CLK_DIV_OFFSET(x) (x * 8)
271 +#define NSS_COMMON_CLK_DIV_MASK 0x7f
272 +
273 +#define NSS_COMMON_CLK_SRC_CTRL 0x14
274 +#define NSS_COMMON_CLK_SRC_CTRL_OFFSET(x) (x)
275 +/* Mode is coded on 1 bit but is different depending on the MAC ID:
276 + * MAC0: QSGMII=0 RGMII=1
277 + * MAC1: QSGMII=0 SGMII=0 RGMII=1
278 + * MAC2 & MAC3: QSGMII=0 SGMII=1
279 + */
280 +#define NSS_COMMON_CLK_SRC_CTRL_RGMII(x) 1
281 +#define NSS_COMMON_CLK_SRC_CTRL_SGMII(x) ((x >= 2) ? 1 : 0)
282 +
283 +#define NSS_COMMON_MACSEC_CTL 0x28
284 +#define NSS_COMMON_MACSEC_CTL_EXT_BYPASS_EN(x) (1 << x)
285 +
286 +#define NSS_COMMON_GMAC_CTL(x) (0x30 + (x * 4))
287 +#define NSS_COMMON_GMAC_CTL_CSYS_REQ BIT(19)
288 +#define NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL BIT(16)
289 +#define NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET 8
290 +#define NSS_COMMON_GMAC_CTL_IFG_OFFSET 0
291 +#define NSS_COMMON_GMAC_CTL_IFG_MASK 0x3f
292 +
293 +#define NSS_COMMON_CLK_DIV_RGMII_1000 1
294 +#define NSS_COMMON_CLK_DIV_RGMII_100 9
295 +#define NSS_COMMON_CLK_DIV_RGMII_10 99
296 +#define NSS_COMMON_CLK_DIV_SGMII_1000 0
297 +#define NSS_COMMON_CLK_DIV_SGMII_100 4
298 +#define NSS_COMMON_CLK_DIV_SGMII_10 49
299 +
300 +#define QSGMII_PCS_MODE_CTL 0x68
301 +#define QSGMII_PCS_MODE_CTL_AUTONEG_EN(x) BIT((x * 8) + 7)
302 +
303 +#define QSGMII_PCS_CAL_LCKDT_CTL 0x120
304 +#define QSGMII_PCS_CAL_LCKDT_CTL_RST BIT(19)
305 +
306 +/* Only GMAC1/2/3 support SGMII and their CTL register are not contiguous */
307 +#define QSGMII_PHY_SGMII_CTL(x) ((x == 1) ? 0x134 : \
308 + (0x13c + (4 * (x - 2))))
309 +#define QSGMII_PHY_CDR_EN BIT(0)
310 +#define QSGMII_PHY_RX_FRONT_EN BIT(1)
311 +#define QSGMII_PHY_RX_SIGNAL_DETECT_EN BIT(2)
312 +#define QSGMII_PHY_TX_DRIVER_EN BIT(3)
313 +#define QSGMII_PHY_QSGMII_EN BIT(7)
314 +#define QSGMII_PHY_PHASE_LOOP_GAIN_OFFSET 12
315 +#define QSGMII_PHY_PHASE_LOOP_GAIN_MASK 0x7
316 +#define QSGMII_PHY_RX_DC_BIAS_OFFSET 18
317 +#define QSGMII_PHY_RX_DC_BIAS_MASK 0x3
318 +#define QSGMII_PHY_RX_INPUT_EQU_OFFSET 20
319 +#define QSGMII_PHY_RX_INPUT_EQU_MASK 0x3
320 +#define QSGMII_PHY_CDR_PI_SLEW_OFFSET 22
321 +#define QSGMII_PHY_CDR_PI_SLEW_MASK 0x3
322 +#define QSGMII_PHY_TX_DRV_AMP_OFFSET 28
323 +#define QSGMII_PHY_TX_DRV_AMP_MASK 0xf
324 +
325 +struct ipq806x_gmac {
326 + struct platform_device *pdev;
327 + struct regmap *nss_common;
328 + struct regmap *qsgmii_csr;
329 + uint32_t id;
330 + struct clk *core_clk;
331 + phy_interface_t phy_mode;
332 +};
333 +
334 +static int get_clk_div_sgmii(struct ipq806x_gmac *gmac, unsigned int speed)
335 +{
336 + struct device *dev = &gmac->pdev->dev;
337 + int div;
338 +
339 + switch (speed) {
340 + case SPEED_1000:
341 + div = NSS_COMMON_CLK_DIV_SGMII_1000;
342 + break;
343 +
344 + case SPEED_100:
345 + div = NSS_COMMON_CLK_DIV_SGMII_100;
346 + break;
347 +
348 + case SPEED_10:
349 + div = NSS_COMMON_CLK_DIV_SGMII_10;
350 + break;
351 +
352 + default:
353 + dev_err(dev, "Speed %dMbps not supported in SGMII\n", speed);
354 + return -EINVAL;
355 + }
356 +
357 + return div;
358 +}
359 +
360 +static int get_clk_div_rgmii(struct ipq806x_gmac *gmac, unsigned int speed)
361 +{
362 + struct device *dev = &gmac->pdev->dev;
363 + int div;
364 +
365 + switch (speed) {
366 + case SPEED_1000:
367 + div = NSS_COMMON_CLK_DIV_RGMII_1000;
368 + break;
369 +
370 + case SPEED_100:
371 + div = NSS_COMMON_CLK_DIV_RGMII_100;
372 + break;
373 +
374 + case SPEED_10:
375 + div = NSS_COMMON_CLK_DIV_RGMII_10;
376 + break;
377 +
378 + default:
379 + dev_err(dev, "Speed %dMbps not supported in RGMII\n", speed);
380 + return -EINVAL;
381 + }
382 +
383 + return div;
384 +}
385 +
386 +static int ipq806x_gmac_set_speed(struct ipq806x_gmac *gmac, unsigned int speed)
387 +{
388 + uint32_t clk_bits, val;
389 + int div;
390 +
391 + switch (gmac->phy_mode) {
392 + case PHY_INTERFACE_MODE_RGMII:
393 + div = get_clk_div_rgmii(gmac, speed);
394 + clk_bits = NSS_COMMON_CLK_GATE_RGMII_RX_EN(gmac->id) |
395 + NSS_COMMON_CLK_GATE_RGMII_TX_EN(gmac->id);
396 + break;
397 +
398 + case PHY_INTERFACE_MODE_SGMII:
399 + div = get_clk_div_sgmii(gmac, speed);
400 + clk_bits = NSS_COMMON_CLK_GATE_GMII_RX_EN(gmac->id) |
401 + NSS_COMMON_CLK_GATE_GMII_TX_EN(gmac->id);
402 + break;
403 +
404 + default:
405 + dev_err(&gmac->pdev->dev, "Unsupported PHY mode: \"%s\"\n",
406 + phy_modes(gmac->phy_mode));
407 + return -EINVAL;
408 + }
409 +
410 + /* Disable the clocks */
411 + regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
412 + val &= ~clk_bits;
413 + regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
414 +
415 + /* Set the divider */
416 + regmap_read(gmac->nss_common, NSS_COMMON_CLK_DIV0, &val);
417 + val &= ~(NSS_COMMON_CLK_DIV_MASK
418 + << NSS_COMMON_CLK_DIV_OFFSET(gmac->id));
419 + val |= div << NSS_COMMON_CLK_DIV_OFFSET(gmac->id);
420 + regmap_write(gmac->nss_common, NSS_COMMON_CLK_DIV0, val);
421 +
422 + /* Enable the clock back */
423 + regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
424 + val |= clk_bits;
425 + regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
426 +
427 + return 0;
428 +}
429 +
430 +static void *ipq806x_gmac_of_parse(struct ipq806x_gmac *gmac)
431 +{
432 + struct device *dev = &gmac->pdev->dev;
433 +
434 + gmac->phy_mode = of_get_phy_mode(dev->of_node);
435 + if (gmac->phy_mode < 0) {
436 + dev_err(dev, "missing phy mode property\n");
437 + return ERR_PTR(-EINVAL);
438 + }
439 +
440 + if (of_property_read_u32(dev->of_node, "qcom,id", &gmac->id) < 0) {
441 + dev_err(dev, "missing qcom id property\n");
442 + return ERR_PTR(-EINVAL);
443 + }
444 +
445 + /* The GMACs are called 1 to 4 in the documentation, but to simplify the
446 + * code and keep it consistent with the Linux convention, we'll number
447 + * them from 0 to 3 here.
448 + */
449 + if (gmac->id < 0 || gmac->id > 3) {
450 + dev_err(dev, "invalid gmac id\n");
451 + return ERR_PTR(-EINVAL);
452 + }
453 +
454 + gmac->core_clk = devm_clk_get(dev, "stmmaceth");
455 + if (IS_ERR(gmac->core_clk)) {
456 + dev_err(dev, "missing stmmaceth clk property\n");
457 + return gmac->core_clk;
458 + }
459 + clk_set_rate(gmac->core_clk, 266000000);
460 +
461 + /* Setup the register map for the nss common registers */
462 + gmac->nss_common = syscon_regmap_lookup_by_phandle(dev->of_node,
463 + "qcom,nss-common");
464 + if (IS_ERR(gmac->nss_common)) {
465 + dev_err(dev, "missing nss-common node\n");
466 + return gmac->nss_common;
467 + }
468 +
469 + /* Setup the register map for the qsgmii csr registers */
470 + gmac->qsgmii_csr = syscon_regmap_lookup_by_phandle(dev->of_node,
471 + "qcom,qsgmii-csr");
472 + if (IS_ERR(gmac->qsgmii_csr)) {
473 + dev_err(dev, "missing qsgmii-csr node\n");
474 + return gmac->qsgmii_csr;
475 + }
476 +
477 + return NULL;
478 +}
479 +
480 +static void ipq806x_gmac_fix_mac_speed(void *priv, unsigned int speed)
481 +{
482 + struct ipq806x_gmac *gmac = priv;
483 +
484 + ipq806x_gmac_set_speed(gmac, speed);
485 +}
486 +
487 +static int ipq806x_gmac_probe(struct platform_device *pdev)
488 +{
489 + struct plat_stmmacenet_data *plat_dat;
490 + struct stmmac_resources stmmac_res;
491 + struct device *dev = &pdev->dev;
492 + struct ipq806x_gmac *gmac;
493 + int val;
494 + void *err;
495 +
496 + val = stmmac_get_platform_resources(pdev, &stmmac_res);
497 + if (val)
498 + return val;
499 +
500 + plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
501 + if (IS_ERR(plat_dat))
502 + return PTR_ERR(plat_dat);
503 +
504 + gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
505 + if (!gmac)
506 + return -ENOMEM;
507 +
508 + gmac->pdev = pdev;
509 +
510 + err = ipq806x_gmac_of_parse(gmac);
511 + if (IS_ERR(err)) {
512 + dev_err(dev, "device tree parsing error\n");
513 + return PTR_ERR(err);
514 + }
515 +
516 + regmap_write(gmac->qsgmii_csr, QSGMII_PCS_CAL_LCKDT_CTL,
517 + QSGMII_PCS_CAL_LCKDT_CTL_RST);
518 +
519 + /* Inter frame gap is set to 12 */
520 + val = 12 << NSS_COMMON_GMAC_CTL_IFG_OFFSET |
521 + 12 << NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET;
522 + /* We also initiate an AXI low power exit request */
523 + val |= NSS_COMMON_GMAC_CTL_CSYS_REQ;
524 + switch (gmac->phy_mode) {
525 + case PHY_INTERFACE_MODE_RGMII:
526 + val |= NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
527 + break;
528 + case PHY_INTERFACE_MODE_SGMII:
529 + val &= ~NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
530 + break;
531 + default:
532 + dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
533 + phy_modes(gmac->phy_mode));
534 + return -EINVAL;
535 + }
536 + regmap_write(gmac->nss_common, NSS_COMMON_GMAC_CTL(gmac->id), val);
537 +
538 + /* Configure the clock src according to the mode */
539 + regmap_read(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, &val);
540 + val &= ~(1 << NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id));
541 + switch (gmac->phy_mode) {
542 + case PHY_INTERFACE_MODE_RGMII:
543 + val |= NSS_COMMON_CLK_SRC_CTRL_RGMII(gmac->id) <<
544 + NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
545 + break;
546 + case PHY_INTERFACE_MODE_SGMII:
547 + val |= NSS_COMMON_CLK_SRC_CTRL_SGMII(gmac->id) <<
548 + NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
549 + break;
550 + default:
551 + dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
552 + phy_modes(gmac->phy_mode));
553 + return -EINVAL;
554 + }
555 + regmap_write(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, val);
556 +
557 + /* Enable PTP clock */
558 + regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
559 + val |= NSS_COMMON_CLK_GATE_PTP_EN(gmac->id);
560 + regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
561 +
562 + if (gmac->phy_mode == PHY_INTERFACE_MODE_SGMII) {
563 + regmap_write(gmac->qsgmii_csr, QSGMII_PHY_SGMII_CTL(gmac->id),
564 + QSGMII_PHY_CDR_EN |
565 + QSGMII_PHY_RX_FRONT_EN |
566 + QSGMII_PHY_RX_SIGNAL_DETECT_EN |
567 + QSGMII_PHY_TX_DRIVER_EN |
568 + QSGMII_PHY_QSGMII_EN |
569 + 0x4 << QSGMII_PHY_PHASE_LOOP_GAIN_OFFSET |
570 + 0x3 << QSGMII_PHY_RX_DC_BIAS_OFFSET |
571 + 0x1 << QSGMII_PHY_RX_INPUT_EQU_OFFSET |
572 + 0x2 << QSGMII_PHY_CDR_PI_SLEW_OFFSET |
573 + 0xC << QSGMII_PHY_TX_DRV_AMP_OFFSET);
574 + }
575 +
576 + plat_dat->has_gmac = true;
577 + plat_dat->bsp_priv = gmac;
578 + plat_dat->fix_mac_speed = ipq806x_gmac_fix_mac_speed;
579 +
580 + return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
581 +}
582 +
583 +static const struct of_device_id ipq806x_gmac_dwmac_match[] = {
584 + { .compatible = "qcom,ipq806x-gmac" },
585 + { }
586 +};
587 +MODULE_DEVICE_TABLE(of, ipq806x_gmac_dwmac_match);
588 +
589 +static struct platform_driver ipq806x_gmac_dwmac_driver = {
590 + .probe = ipq806x_gmac_probe,
591 + .remove = stmmac_pltfr_remove,
592 + .driver = {
593 + .name = "ipq806x-gmac-dwmac",
594 + .pm = &stmmac_pltfr_pm_ops,
595 + .of_match_table = ipq806x_gmac_dwmac_match,
596 + },
597 +};
598 +module_platform_driver(ipq806x_gmac_dwmac_driver);
599 +
600 +MODULE_AUTHOR("Mathieu Olivari <mathieu@codeaurora.org>");
601 +MODULE_DESCRIPTION("Qualcomm Atheros IPQ806x DWMAC specific glue layer");
602 +MODULE_LICENSE("Dual BSD/GPL");
603 --- /dev/null
604 +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c
605 @@ -0,0 +1,86 @@
606 +/*
607 + * DWMAC glue for NXP LPC18xx/LPC43xx Ethernet
608 + *
609 + * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
610 + *
611 + * This file is licensed under the terms of the GNU General Public
612 + * License version 2. This program is licensed "as is" without any
613 + * warranty of any kind, whether express or implied.
614 + */
615 +
616 +#include <linux/mfd/syscon.h>
617 +#include <linux/module.h>
618 +#include <linux/of.h>
619 +#include <linux/of_net.h>
620 +#include <linux/phy.h>
621 +#include <linux/platform_device.h>
622 +#include <linux/regmap.h>
623 +#include <linux/stmmac.h>
624 +
625 +#include "stmmac_platform.h"
626 +
627 +/* Register defines for CREG syscon */
628 +#define LPC18XX_CREG_CREG6 0x12c
629 +# define LPC18XX_CREG_CREG6_ETHMODE_MASK 0x7
630 +# define LPC18XX_CREG_CREG6_ETHMODE_MII 0x0
631 +# define LPC18XX_CREG_CREG6_ETHMODE_RMII 0x4
632 +
633 +static int lpc18xx_dwmac_probe(struct platform_device *pdev)
634 +{
635 + struct plat_stmmacenet_data *plat_dat;
636 + struct stmmac_resources stmmac_res;
637 + struct regmap *reg;
638 + u8 ethmode;
639 + int ret;
640 +
641 + ret = stmmac_get_platform_resources(pdev, &stmmac_res);
642 + if (ret)
643 + return ret;
644 +
645 + plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
646 + if (IS_ERR(plat_dat))
647 + return PTR_ERR(plat_dat);
648 +
649 + plat_dat->has_gmac = true;
650 +
651 + reg = syscon_regmap_lookup_by_compatible("nxp,lpc1850-creg");
652 + if (IS_ERR(reg)) {
653 + dev_err(&pdev->dev, "syscon lookup failed\n");
654 + return PTR_ERR(reg);
655 + }
656 +
657 + if (plat_dat->interface == PHY_INTERFACE_MODE_MII) {
658 + ethmode = LPC18XX_CREG_CREG6_ETHMODE_MII;
659 + } else if (plat_dat->interface == PHY_INTERFACE_MODE_RMII) {
660 + ethmode = LPC18XX_CREG_CREG6_ETHMODE_RMII;
661 + } else {
662 + dev_err(&pdev->dev, "Only MII and RMII mode supported\n");
663 + return -EINVAL;
664 + }
665 +
666 + regmap_update_bits(reg, LPC18XX_CREG_CREG6,
667 + LPC18XX_CREG_CREG6_ETHMODE_MASK, ethmode);
668 +
669 + return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
670 +}
671 +
672 +static const struct of_device_id lpc18xx_dwmac_match[] = {
673 + { .compatible = "nxp,lpc1850-dwmac" },
674 + { }
675 +};
676 +MODULE_DEVICE_TABLE(of, lpc18xx_dwmac_match);
677 +
678 +static struct platform_driver lpc18xx_dwmac_driver = {
679 + .probe = lpc18xx_dwmac_probe,
680 + .remove = stmmac_pltfr_remove,
681 + .driver = {
682 + .name = "lpc18xx-dwmac",
683 + .pm = &stmmac_pltfr_pm_ops,
684 + .of_match_table = lpc18xx_dwmac_match,
685 + },
686 +};
687 +module_platform_driver(lpc18xx_dwmac_driver);
688 +
689 +MODULE_AUTHOR("Joachim Eastwood <manabian@gmail.com>");
690 +MODULE_DESCRIPTION("DWMAC glue for LPC18xx/43xx Ethernet");
691 +MODULE_LICENSE("GPL v2");
692 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
693 +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson.c
694 @@ -15,6 +15,7 @@
695 #include <linux/ethtool.h>
696 #include <linux/io.h>
697 #include <linux/ioport.h>
698 +#include <linux/module.h>
699 #include <linux/platform_device.h>
700 #include <linux/stmmac.h>
701
702 @@ -46,24 +47,54 @@ static void meson6_dwmac_fix_mac_speed(v
703 writel(val, dwmac->reg);
704 }
705
706 -static void *meson6_dwmac_setup(struct platform_device *pdev)
707 +static int meson6_dwmac_probe(struct platform_device *pdev)
708 {
709 + struct plat_stmmacenet_data *plat_dat;
710 + struct stmmac_resources stmmac_res;
711 struct meson_dwmac *dwmac;
712 struct resource *res;
713 + int ret;
714 +
715 + ret = stmmac_get_platform_resources(pdev, &stmmac_res);
716 + if (ret)
717 + return ret;
718 +
719 + plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
720 + if (IS_ERR(plat_dat))
721 + return PTR_ERR(plat_dat);
722
723 dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
724 if (!dwmac)
725 - return ERR_PTR(-ENOMEM);
726 + return -ENOMEM;
727
728 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
729 dwmac->reg = devm_ioremap_resource(&pdev->dev, res);
730 if (IS_ERR(dwmac->reg))
731 - return ERR_CAST(dwmac->reg);
732 + return PTR_ERR(dwmac->reg);
733 +
734 + plat_dat->bsp_priv = dwmac;
735 + plat_dat->fix_mac_speed = meson6_dwmac_fix_mac_speed;
736
737 - return dwmac;
738 + return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
739 }
740
741 -const struct stmmac_of_data meson6_dwmac_data = {
742 - .setup = meson6_dwmac_setup,
743 - .fix_mac_speed = meson6_dwmac_fix_mac_speed,
744 +static const struct of_device_id meson6_dwmac_match[] = {
745 + { .compatible = "amlogic,meson6-dwmac" },
746 + { }
747 };
748 +MODULE_DEVICE_TABLE(of, meson6_dwmac_match);
749 +
750 +static struct platform_driver meson6_dwmac_driver = {
751 + .probe = meson6_dwmac_probe,
752 + .remove = stmmac_pltfr_remove,
753 + .driver = {
754 + .name = "meson6-dwmac",
755 + .pm = &stmmac_pltfr_pm_ops,
756 + .of_match_table = meson6_dwmac_match,
757 + },
758 +};
759 +module_platform_driver(meson6_dwmac_driver);
760 +
761 +MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>");
762 +MODULE_DESCRIPTION("Amlogic Meson DWMAC glue layer");
763 +MODULE_LICENSE("GPL v2");
764 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
765 +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
766 @@ -22,17 +22,31 @@
767 #include <linux/phy.h>
768 #include <linux/of_net.h>
769 #include <linux/gpio.h>
770 +#include <linux/module.h>
771 #include <linux/of_gpio.h>
772 #include <linux/of_device.h>
773 +#include <linux/platform_device.h>
774 #include <linux/regulator/consumer.h>
775 #include <linux/delay.h>
776 #include <linux/mfd/syscon.h>
777 #include <linux/regmap.h>
778
779 +#include "stmmac_platform.h"
780 +
781 +struct rk_priv_data;
782 +struct rk_gmac_ops {
783 + void (*set_to_rgmii)(struct rk_priv_data *bsp_priv,
784 + int tx_delay, int rx_delay);
785 + void (*set_to_rmii)(struct rk_priv_data *bsp_priv);
786 + void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed);
787 + void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed);
788 +};
789 +
790 struct rk_priv_data {
791 struct platform_device *pdev;
792 int phy_iface;
793 struct regulator *regulator;
794 + const struct rk_gmac_ops *ops;
795
796 bool clk_enabled;
797 bool clock_input;
798 @@ -60,103 +74,228 @@ struct rk_priv_data {
799
800 #define RK3288_GRF_SOC_CON1 0x0248
801 #define RK3288_GRF_SOC_CON3 0x0250
802 -#define RK3288_GRF_GPIO3D_E 0x01ec
803 -#define RK3288_GRF_GPIO4A_E 0x01f0
804 -#define RK3288_GRF_GPIO4B_E 0x01f4
805
806 /*RK3288_GRF_SOC_CON1*/
807 -#define GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(6) | GRF_CLR_BIT(7) | GRF_CLR_BIT(8))
808 -#define GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | GRF_BIT(8))
809 -#define GMAC_FLOW_CTRL GRF_BIT(9)
810 -#define GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(9)
811 -#define GMAC_SPEED_10M GRF_CLR_BIT(10)
812 -#define GMAC_SPEED_100M GRF_BIT(10)
813 -#define GMAC_RMII_CLK_25M GRF_BIT(11)
814 -#define GMAC_RMII_CLK_2_5M GRF_CLR_BIT(11)
815 -#define GMAC_CLK_125M (GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
816 -#define GMAC_CLK_25M (GRF_BIT(12) | GRF_BIT(13))
817 -#define GMAC_CLK_2_5M (GRF_CLR_BIT(12) | GRF_BIT(13))
818 -#define GMAC_RMII_MODE GRF_BIT(14)
819 -#define GMAC_RMII_MODE_CLR GRF_CLR_BIT(14)
820 +#define RK3288_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(6) | GRF_CLR_BIT(7) | \
821 + GRF_CLR_BIT(8))
822 +#define RK3288_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | \
823 + GRF_BIT(8))
824 +#define RK3288_GMAC_FLOW_CTRL GRF_BIT(9)
825 +#define RK3288_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(9)
826 +#define RK3288_GMAC_SPEED_10M GRF_CLR_BIT(10)
827 +#define RK3288_GMAC_SPEED_100M GRF_BIT(10)
828 +#define RK3288_GMAC_RMII_CLK_25M GRF_BIT(11)
829 +#define RK3288_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(11)
830 +#define RK3288_GMAC_CLK_125M (GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
831 +#define RK3288_GMAC_CLK_25M (GRF_BIT(12) | GRF_BIT(13))
832 +#define RK3288_GMAC_CLK_2_5M (GRF_CLR_BIT(12) | GRF_BIT(13))
833 +#define RK3288_GMAC_RMII_MODE GRF_BIT(14)
834 +#define RK3288_GMAC_RMII_MODE_CLR GRF_CLR_BIT(14)
835
836 /*RK3288_GRF_SOC_CON3*/
837 -#define GMAC_TXCLK_DLY_ENABLE GRF_BIT(14)
838 -#define GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14)
839 -#define GMAC_RXCLK_DLY_ENABLE GRF_BIT(15)
840 -#define GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15)
841 -#define GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
842 -#define GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
843 +#define RK3288_GMAC_TXCLK_DLY_ENABLE GRF_BIT(14)
844 +#define RK3288_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14)
845 +#define RK3288_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15)
846 +#define RK3288_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15)
847 +#define RK3288_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
848 +#define RK3288_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
849
850 -static void set_to_rgmii(struct rk_priv_data *bsp_priv,
851 - int tx_delay, int rx_delay)
852 +static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv,
853 + int tx_delay, int rx_delay)
854 {
855 struct device *dev = &bsp_priv->pdev->dev;
856
857 if (IS_ERR(bsp_priv->grf)) {
858 - dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
859 + dev_err(dev, "Missing rockchip,grf property\n");
860 return;
861 }
862
863 regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
864 - GMAC_PHY_INTF_SEL_RGMII | GMAC_RMII_MODE_CLR);
865 + RK3288_GMAC_PHY_INTF_SEL_RGMII |
866 + RK3288_GMAC_RMII_MODE_CLR);
867 regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3,
868 - GMAC_RXCLK_DLY_ENABLE | GMAC_TXCLK_DLY_ENABLE |
869 - GMAC_CLK_RX_DL_CFG(rx_delay) |
870 - GMAC_CLK_TX_DL_CFG(tx_delay));
871 + RK3288_GMAC_RXCLK_DLY_ENABLE |
872 + RK3288_GMAC_TXCLK_DLY_ENABLE |
873 + RK3288_GMAC_CLK_RX_DL_CFG(rx_delay) |
874 + RK3288_GMAC_CLK_TX_DL_CFG(tx_delay));
875 }
876
877 -static void set_to_rmii(struct rk_priv_data *bsp_priv)
878 +static void rk3288_set_to_rmii(struct rk_priv_data *bsp_priv)
879 {
880 struct device *dev = &bsp_priv->pdev->dev;
881
882 if (IS_ERR(bsp_priv->grf)) {
883 - dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
884 + dev_err(dev, "Missing rockchip,grf property\n");
885 return;
886 }
887
888 regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
889 - GMAC_PHY_INTF_SEL_RMII | GMAC_RMII_MODE);
890 + RK3288_GMAC_PHY_INTF_SEL_RMII | RK3288_GMAC_RMII_MODE);
891 }
892
893 -static void set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
894 +static void rk3288_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
895 {
896 struct device *dev = &bsp_priv->pdev->dev;
897
898 if (IS_ERR(bsp_priv->grf)) {
899 - dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
900 + dev_err(dev, "Missing rockchip,grf property\n");
901 return;
902 }
903
904 if (speed == 10)
905 - regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, GMAC_CLK_2_5M);
906 + regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
907 + RK3288_GMAC_CLK_2_5M);
908 else if (speed == 100)
909 - regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, GMAC_CLK_25M);
910 + regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
911 + RK3288_GMAC_CLK_25M);
912 else if (speed == 1000)
913 - regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, GMAC_CLK_125M);
914 + regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
915 + RK3288_GMAC_CLK_125M);
916 else
917 dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
918 }
919
920 -static void set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
921 +static void rk3288_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
922 {
923 struct device *dev = &bsp_priv->pdev->dev;
924
925 if (IS_ERR(bsp_priv->grf)) {
926 - dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
927 + dev_err(dev, "Missing rockchip,grf property\n");
928 return;
929 }
930
931 if (speed == 10) {
932 regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
933 - GMAC_RMII_CLK_2_5M | GMAC_SPEED_10M);
934 + RK3288_GMAC_RMII_CLK_2_5M |
935 + RK3288_GMAC_SPEED_10M);
936 } else if (speed == 100) {
937 regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
938 - GMAC_RMII_CLK_25M | GMAC_SPEED_100M);
939 + RK3288_GMAC_RMII_CLK_25M |
940 + RK3288_GMAC_SPEED_100M);
941 + } else {
942 + dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
943 + }
944 +}
945 +
946 +static const struct rk_gmac_ops rk3288_ops = {
947 + .set_to_rgmii = rk3288_set_to_rgmii,
948 + .set_to_rmii = rk3288_set_to_rmii,
949 + .set_rgmii_speed = rk3288_set_rgmii_speed,
950 + .set_rmii_speed = rk3288_set_rmii_speed,
951 +};
952 +
953 +#define RK3368_GRF_SOC_CON15 0x043c
954 +#define RK3368_GRF_SOC_CON16 0x0440
955 +
956 +/* RK3368_GRF_SOC_CON15 */
957 +#define RK3368_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \
958 + GRF_CLR_BIT(11))
959 +#define RK3368_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
960 + GRF_BIT(11))
961 +#define RK3368_GMAC_FLOW_CTRL GRF_BIT(8)
962 +#define RK3368_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8)
963 +#define RK3368_GMAC_SPEED_10M GRF_CLR_BIT(7)
964 +#define RK3368_GMAC_SPEED_100M GRF_BIT(7)
965 +#define RK3368_GMAC_RMII_CLK_25M GRF_BIT(3)
966 +#define RK3368_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3)
967 +#define RK3368_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
968 +#define RK3368_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5))
969 +#define RK3368_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5))
970 +#define RK3368_GMAC_RMII_MODE GRF_BIT(6)
971 +#define RK3368_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6)
972 +
973 +/* RK3368_GRF_SOC_CON16 */
974 +#define RK3368_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7)
975 +#define RK3368_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7)
976 +#define RK3368_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15)
977 +#define RK3368_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15)
978 +#define RK3368_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8)
979 +#define RK3368_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
980 +
981 +static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv,
982 + int tx_delay, int rx_delay)
983 +{
984 + struct device *dev = &bsp_priv->pdev->dev;
985 +
986 + if (IS_ERR(bsp_priv->grf)) {
987 + dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
988 + return;
989 + }
990 +
991 + regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
992 + RK3368_GMAC_PHY_INTF_SEL_RGMII |
993 + RK3368_GMAC_RMII_MODE_CLR);
994 + regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16,
995 + RK3368_GMAC_RXCLK_DLY_ENABLE |
996 + RK3368_GMAC_TXCLK_DLY_ENABLE |
997 + RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) |
998 + RK3368_GMAC_CLK_TX_DL_CFG(tx_delay));
999 +}
1000 +
1001 +static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv)
1002 +{
1003 + struct device *dev = &bsp_priv->pdev->dev;
1004 +
1005 + if (IS_ERR(bsp_priv->grf)) {
1006 + dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
1007 + return;
1008 + }
1009 +
1010 + regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
1011 + RK3368_GMAC_PHY_INTF_SEL_RMII | RK3368_GMAC_RMII_MODE);
1012 +}
1013 +
1014 +static void rk3368_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
1015 +{
1016 + struct device *dev = &bsp_priv->pdev->dev;
1017 +
1018 + if (IS_ERR(bsp_priv->grf)) {
1019 + dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
1020 + return;
1021 + }
1022 +
1023 + if (speed == 10)
1024 + regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
1025 + RK3368_GMAC_CLK_2_5M);
1026 + else if (speed == 100)
1027 + regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
1028 + RK3368_GMAC_CLK_25M);
1029 + else if (speed == 1000)
1030 + regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
1031 + RK3368_GMAC_CLK_125M);
1032 + else
1033 + dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
1034 +}
1035 +
1036 +static void rk3368_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
1037 +{
1038 + struct device *dev = &bsp_priv->pdev->dev;
1039 +
1040 + if (IS_ERR(bsp_priv->grf)) {
1041 + dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
1042 + return;
1043 + }
1044 +
1045 + if (speed == 10) {
1046 + regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
1047 + RK3368_GMAC_RMII_CLK_2_5M |
1048 + RK3368_GMAC_SPEED_10M);
1049 + } else if (speed == 100) {
1050 + regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
1051 + RK3368_GMAC_RMII_CLK_25M |
1052 + RK3368_GMAC_SPEED_100M);
1053 } else {
1054 dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
1055 }
1056 }
1057
1058 +static const struct rk_gmac_ops rk3368_ops = {
1059 + .set_to_rgmii = rk3368_set_to_rgmii,
1060 + .set_to_rmii = rk3368_set_to_rmii,
1061 + .set_rgmii_speed = rk3368_set_rgmii_speed,
1062 + .set_rmii_speed = rk3368_set_rmii_speed,
1063 +};
1064 +
1065 static int gmac_clk_init(struct rk_priv_data *bsp_priv)
1066 {
1067 struct device *dev = &bsp_priv->pdev->dev;
1068 @@ -165,46 +304,46 @@ static int gmac_clk_init(struct rk_priv_
1069
1070 bsp_priv->mac_clk_rx = devm_clk_get(dev, "mac_clk_rx");
1071 if (IS_ERR(bsp_priv->mac_clk_rx))
1072 - dev_err(dev, "%s: cannot get clock %s\n",
1073 - __func__, "mac_clk_rx");
1074 + dev_err(dev, "cannot get clock %s\n",
1075 + "mac_clk_rx");
1076
1077 bsp_priv->mac_clk_tx = devm_clk_get(dev, "mac_clk_tx");
1078 if (IS_ERR(bsp_priv->mac_clk_tx))
1079 - dev_err(dev, "%s: cannot get clock %s\n",
1080 - __func__, "mac_clk_tx");
1081 + dev_err(dev, "cannot get clock %s\n",
1082 + "mac_clk_tx");
1083
1084 bsp_priv->aclk_mac = devm_clk_get(dev, "aclk_mac");
1085 if (IS_ERR(bsp_priv->aclk_mac))
1086 - dev_err(dev, "%s: cannot get clock %s\n",
1087 - __func__, "aclk_mac");
1088 + dev_err(dev, "cannot get clock %s\n",
1089 + "aclk_mac");
1090
1091 bsp_priv->pclk_mac = devm_clk_get(dev, "pclk_mac");
1092 if (IS_ERR(bsp_priv->pclk_mac))
1093 - dev_err(dev, "%s: cannot get clock %s\n",
1094 - __func__, "pclk_mac");
1095 + dev_err(dev, "cannot get clock %s\n",
1096 + "pclk_mac");
1097
1098 bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth");
1099 if (IS_ERR(bsp_priv->clk_mac))
1100 - dev_err(dev, "%s: cannot get clock %s\n",
1101 - __func__, "stmmaceth");
1102 + dev_err(dev, "cannot get clock %s\n",
1103 + "stmmaceth");
1104
1105 if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) {
1106 bsp_priv->clk_mac_ref = devm_clk_get(dev, "clk_mac_ref");
1107 if (IS_ERR(bsp_priv->clk_mac_ref))
1108 - dev_err(dev, "%s: cannot get clock %s\n",
1109 - __func__, "clk_mac_ref");
1110 + dev_err(dev, "cannot get clock %s\n",
1111 + "clk_mac_ref");
1112
1113 if (!bsp_priv->clock_input) {
1114 bsp_priv->clk_mac_refout =
1115 devm_clk_get(dev, "clk_mac_refout");
1116 if (IS_ERR(bsp_priv->clk_mac_refout))
1117 - dev_err(dev, "%s: cannot get clock %s\n",
1118 - __func__, "clk_mac_refout");
1119 + dev_err(dev, "cannot get clock %s\n",
1120 + "clk_mac_refout");
1121 }
1122 }
1123
1124 if (bsp_priv->clock_input) {
1125 - dev_info(dev, "%s: clock input from PHY\n", __func__);
1126 + dev_info(dev, "clock input from PHY\n");
1127 } else {
1128 if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
1129 clk_set_rate(bsp_priv->clk_mac, 50000000);
1130 @@ -291,26 +430,25 @@ static int phy_power_on(struct rk_priv_d
1131 struct device *dev = &bsp_priv->pdev->dev;
1132
1133 if (!ldo) {
1134 - dev_err(dev, "%s: no regulator found\n", __func__);
1135 + dev_err(dev, "no regulator found\n");
1136 return -1;
1137 }
1138
1139 if (enable) {
1140 ret = regulator_enable(ldo);
1141 if (ret)
1142 - dev_err(dev, "%s: fail to enable phy-supply\n",
1143 - __func__);
1144 + dev_err(dev, "fail to enable phy-supply\n");
1145 } else {
1146 ret = regulator_disable(ldo);
1147 if (ret)
1148 - dev_err(dev, "%s: fail to disable phy-supply\n",
1149 - __func__);
1150 + dev_err(dev, "fail to disable phy-supply\n");
1151 }
1152
1153 return 0;
1154 }
1155
1156 -static void *rk_gmac_setup(struct platform_device *pdev)
1157 +static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
1158 + const struct rk_gmac_ops *ops)
1159 {
1160 struct rk_priv_data *bsp_priv;
1161 struct device *dev = &pdev->dev;
1162 @@ -323,6 +461,7 @@ static void *rk_gmac_setup(struct platfo
1163 return ERR_PTR(-ENOMEM);
1164
1165 bsp_priv->phy_iface = of_get_phy_mode(dev->of_node);
1166 + bsp_priv->ops = ops;
1167
1168 bsp_priv->regulator = devm_regulator_get_optional(dev, "phy");
1169 if (IS_ERR(bsp_priv->regulator)) {
1170 @@ -336,12 +475,11 @@ static void *rk_gmac_setup(struct platfo
1171
1172 ret = of_property_read_string(dev->of_node, "clock_in_out", &strings);
1173 if (ret) {
1174 - dev_err(dev, "%s: Can not read property: clock_in_out.\n",
1175 - __func__);
1176 + dev_err(dev, "Can not read property: clock_in_out.\n");
1177 bsp_priv->clock_input = true;
1178 } else {
1179 - dev_info(dev, "%s: clock input or output? (%s).\n",
1180 - __func__, strings);
1181 + dev_info(dev, "clock input or output? (%s).\n",
1182 + strings);
1183 if (!strcmp(strings, "input"))
1184 bsp_priv->clock_input = true;
1185 else
1186 @@ -351,22 +489,22 @@ static void *rk_gmac_setup(struct platfo
1187 ret = of_property_read_u32(dev->of_node, "tx_delay", &value);
1188 if (ret) {
1189 bsp_priv->tx_delay = 0x30;
1190 - dev_err(dev, "%s: Can not read property: tx_delay.", __func__);
1191 - dev_err(dev, "%s: set tx_delay to 0x%x\n",
1192 - __func__, bsp_priv->tx_delay);
1193 + dev_err(dev, "Can not read property: tx_delay.");
1194 + dev_err(dev, "set tx_delay to 0x%x\n",
1195 + bsp_priv->tx_delay);
1196 } else {
1197 - dev_info(dev, "%s: TX delay(0x%x).\n", __func__, value);
1198 + dev_info(dev, "TX delay(0x%x).\n", value);
1199 bsp_priv->tx_delay = value;
1200 }
1201
1202 ret = of_property_read_u32(dev->of_node, "rx_delay", &value);
1203 if (ret) {
1204 bsp_priv->rx_delay = 0x10;
1205 - dev_err(dev, "%s: Can not read property: rx_delay.", __func__);
1206 - dev_err(dev, "%s: set rx_delay to 0x%x\n",
1207 - __func__, bsp_priv->rx_delay);
1208 + dev_err(dev, "Can not read property: rx_delay.");
1209 + dev_err(dev, "set rx_delay to 0x%x\n",
1210 + bsp_priv->rx_delay);
1211 } else {
1212 - dev_info(dev, "%s: RX delay(0x%x).\n", __func__, value);
1213 + dev_info(dev, "RX delay(0x%x).\n", value);
1214 bsp_priv->rx_delay = value;
1215 }
1216
1217 @@ -376,13 +514,14 @@ static void *rk_gmac_setup(struct platfo
1218
1219 /*rmii or rgmii*/
1220 if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RGMII) {
1221 - dev_info(dev, "%s: init for RGMII\n", __func__);
1222 - set_to_rgmii(bsp_priv, bsp_priv->tx_delay, bsp_priv->rx_delay);
1223 + dev_info(dev, "init for RGMII\n");
1224 + bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay,
1225 + bsp_priv->rx_delay);
1226 } else if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) {
1227 - dev_info(dev, "%s: init for RMII\n", __func__);
1228 - set_to_rmii(bsp_priv);
1229 + dev_info(dev, "init for RMII\n");
1230 + bsp_priv->ops->set_to_rmii(bsp_priv);
1231 } else {
1232 - dev_err(dev, "%s: NO interface defined!\n", __func__);
1233 + dev_err(dev, "NO interface defined!\n");
1234 }
1235
1236 gmac_clk_init(bsp_priv);
1237 @@ -420,17 +559,68 @@ static void rk_fix_speed(void *priv, uns
1238 struct device *dev = &bsp_priv->pdev->dev;
1239
1240 if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RGMII)
1241 - set_rgmii_speed(bsp_priv, speed);
1242 + bsp_priv->ops->set_rgmii_speed(bsp_priv, speed);
1243 else if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
1244 - set_rmii_speed(bsp_priv, speed);
1245 + bsp_priv->ops->set_rmii_speed(bsp_priv, speed);
1246 else
1247 dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface);
1248 }
1249
1250 -const struct stmmac_of_data rk3288_gmac_data = {
1251 - .has_gmac = 1,
1252 - .fix_mac_speed = rk_fix_speed,
1253 - .setup = rk_gmac_setup,
1254 - .init = rk_gmac_init,
1255 - .exit = rk_gmac_exit,
1256 +static int rk_gmac_probe(struct platform_device *pdev)
1257 +{
1258 + struct plat_stmmacenet_data *plat_dat;
1259 + struct stmmac_resources stmmac_res;
1260 + const struct rk_gmac_ops *data;
1261 + int ret;
1262 +
1263 + data = of_device_get_match_data(&pdev->dev);
1264 + if (!data) {
1265 + dev_err(&pdev->dev, "no of match data provided\n");
1266 + return -EINVAL;
1267 + }
1268 +
1269 + ret = stmmac_get_platform_resources(pdev, &stmmac_res);
1270 + if (ret)
1271 + return ret;
1272 +
1273 + plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
1274 + if (IS_ERR(plat_dat))
1275 + return PTR_ERR(plat_dat);
1276 +
1277 + plat_dat->has_gmac = true;
1278 + plat_dat->init = rk_gmac_init;
1279 + plat_dat->exit = rk_gmac_exit;
1280 + plat_dat->fix_mac_speed = rk_fix_speed;
1281 +
1282 + plat_dat->bsp_priv = rk_gmac_setup(pdev, data);
1283 + if (IS_ERR(plat_dat->bsp_priv))
1284 + return PTR_ERR(plat_dat->bsp_priv);
1285 +
1286 + ret = rk_gmac_init(pdev, plat_dat->bsp_priv);
1287 + if (ret)
1288 + return ret;
1289 +
1290 + return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
1291 +}
1292 +
1293 +static const struct of_device_id rk_gmac_dwmac_match[] = {
1294 + { .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops },
1295 + { .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops },
1296 + { }
1297 };
1298 +MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match);
1299 +
1300 +static struct platform_driver rk_gmac_dwmac_driver = {
1301 + .probe = rk_gmac_probe,
1302 + .remove = stmmac_pltfr_remove,
1303 + .driver = {
1304 + .name = "rk_gmac-dwmac",
1305 + .pm = &stmmac_pltfr_pm_ops,
1306 + .of_match_table = rk_gmac_dwmac_match,
1307 + },
1308 +};
1309 +module_platform_driver(rk_gmac_dwmac_driver);
1310 +
1311 +MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>");
1312 +MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer");
1313 +MODULE_LICENSE("GPL");
1314 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
1315 +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
1316 @@ -175,31 +175,6 @@ static int socfpga_dwmac_setup(struct so
1317 return 0;
1318 }
1319
1320 -static void *socfpga_dwmac_probe(struct platform_device *pdev)
1321 -{
1322 - struct device *dev = &pdev->dev;
1323 - int ret;
1324 - struct socfpga_dwmac *dwmac;
1325 -
1326 - dwmac = devm_kzalloc(dev, sizeof(*dwmac), GFP_KERNEL);
1327 - if (!dwmac)
1328 - return ERR_PTR(-ENOMEM);
1329 -
1330 - ret = socfpga_dwmac_parse_data(dwmac, dev);
1331 - if (ret) {
1332 - dev_err(dev, "Unable to parse OF data\n");
1333 - return ERR_PTR(ret);
1334 - }
1335 -
1336 - ret = socfpga_dwmac_setup(dwmac);
1337 - if (ret) {
1338 - dev_err(dev, "couldn't setup SoC glue (%d)\n", ret);
1339 - return ERR_PTR(ret);
1340 - }
1341 -
1342 - return dwmac;
1343 -}
1344 -
1345 static void socfpga_dwmac_exit(struct platform_device *pdev, void *priv)
1346 {
1347 struct socfpga_dwmac *dwmac = priv;
1348 @@ -257,9 +232,65 @@ static int socfpga_dwmac_init(struct pla
1349 return ret;
1350 }
1351
1352 -const struct stmmac_of_data socfpga_gmac_data = {
1353 - .setup = socfpga_dwmac_probe,
1354 - .init = socfpga_dwmac_init,
1355 - .exit = socfpga_dwmac_exit,
1356 - .fix_mac_speed = socfpga_dwmac_fix_mac_speed,
1357 +static int socfpga_dwmac_probe(struct platform_device *pdev)
1358 +{
1359 + struct plat_stmmacenet_data *plat_dat;
1360 + struct stmmac_resources stmmac_res;
1361 + struct device *dev = &pdev->dev;
1362 + int ret;
1363 + struct socfpga_dwmac *dwmac;
1364 +
1365 + ret = stmmac_get_platform_resources(pdev, &stmmac_res);
1366 + if (ret)
1367 + return ret;
1368 +
1369 + plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
1370 + if (IS_ERR(plat_dat))
1371 + return PTR_ERR(plat_dat);
1372 +
1373 + dwmac = devm_kzalloc(dev, sizeof(*dwmac), GFP_KERNEL);
1374 + if (!dwmac)
1375 + return -ENOMEM;
1376 +
1377 + ret = socfpga_dwmac_parse_data(dwmac, dev);
1378 + if (ret) {
1379 + dev_err(dev, "Unable to parse OF data\n");
1380 + return ret;
1381 + }
1382 +
1383 + ret = socfpga_dwmac_setup(dwmac);
1384 + if (ret) {
1385 + dev_err(dev, "couldn't setup SoC glue (%d)\n", ret);
1386 + return ret;
1387 + }
1388 +
1389 + plat_dat->bsp_priv = dwmac;
1390 + plat_dat->init = socfpga_dwmac_init;
1391 + plat_dat->exit = socfpga_dwmac_exit;
1392 + plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed;
1393 +
1394 + ret = socfpga_dwmac_init(pdev, plat_dat->bsp_priv);
1395 + if (ret)
1396 + return ret;
1397 +
1398 + return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
1399 +}
1400 +
1401 +static const struct of_device_id socfpga_dwmac_match[] = {
1402 + { .compatible = "altr,socfpga-stmmac" },
1403 + { }
1404 };
1405 +MODULE_DEVICE_TABLE(of, socfpga_dwmac_match);
1406 +
1407 +static struct platform_driver socfpga_dwmac_driver = {
1408 + .probe = socfpga_dwmac_probe,
1409 + .remove = stmmac_pltfr_remove,
1410 + .driver = {
1411 + .name = "socfpga-dwmac",
1412 + .pm = &stmmac_pltfr_pm_ops,
1413 + .of_match_table = socfpga_dwmac_match,
1414 + },
1415 +};
1416 +module_platform_driver(socfpga_dwmac_driver);
1417 +
1418 +MODULE_LICENSE("GPL v2");
1419 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
1420 +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
1421 @@ -17,9 +17,11 @@
1422 #include <linux/stmmac.h>
1423 #include <linux/phy.h>
1424 #include <linux/mfd/syscon.h>
1425 +#include <linux/module.h>
1426 #include <linux/regmap.h>
1427 #include <linux/clk.h>
1428 #include <linux/of.h>
1429 +#include <linux/of_device.h>
1430 #include <linux/of_net.h>
1431
1432 #include "stmmac_platform.h"
1433 @@ -127,6 +129,11 @@ struct sti_dwmac {
1434 struct device *dev;
1435 struct regmap *regmap;
1436 u32 speed;
1437 + void (*fix_retime_src)(void *priv, unsigned int speed);
1438 +};
1439 +
1440 +struct sti_dwmac_of_data {
1441 + void (*fix_retime_src)(void *priv, unsigned int speed);
1442 };
1443
1444 static u32 phy_intf_sels[] = {
1445 @@ -221,8 +228,9 @@ static void stid127_fix_retime_src(void
1446 regmap_update_bits(dwmac->regmap, reg, STID127_RETIME_SRC_MASK, val);
1447 }
1448
1449 -static void sti_dwmac_ctrl_init(struct sti_dwmac *dwmac)
1450 +static int sti_dwmac_init(struct platform_device *pdev, void *priv)
1451 {
1452 + struct sti_dwmac *dwmac = priv;
1453 struct regmap *regmap = dwmac->regmap;
1454 int iface = dwmac->interface;
1455 struct device *dev = dwmac->dev;
1456 @@ -240,28 +248,8 @@ static void sti_dwmac_ctrl_init(struct s
1457
1458 val = (iface == PHY_INTERFACE_MODE_REVMII) ? 0 : ENMII;
1459 regmap_update_bits(regmap, reg, ENMII_MASK, val);
1460 -}
1461 -
1462 -static int stix4xx_init(struct platform_device *pdev, void *priv)
1463 -{
1464 - struct sti_dwmac *dwmac = priv;
1465 - u32 spd = dwmac->speed;
1466
1467 - sti_dwmac_ctrl_init(dwmac);
1468 -
1469 - stih4xx_fix_retime_src(priv, spd);
1470 -
1471 - return 0;
1472 -}
1473 -
1474 -static int stid127_init(struct platform_device *pdev, void *priv)
1475 -{
1476 - struct sti_dwmac *dwmac = priv;
1477 - u32 spd = dwmac->speed;
1478 -
1479 - sti_dwmac_ctrl_init(dwmac);
1480 -
1481 - stid127_fix_retime_src(priv, spd);
1482 + dwmac->fix_retime_src(priv, dwmac->speed);
1483
1484 return 0;
1485 }
1486 @@ -333,34 +321,80 @@ static int sti_dwmac_parse_data(struct s
1487 return 0;
1488 }
1489
1490 -static void *sti_dwmac_setup(struct platform_device *pdev)
1491 +static int sti_dwmac_probe(struct platform_device *pdev)
1492 {
1493 + struct plat_stmmacenet_data *plat_dat;
1494 + const struct sti_dwmac_of_data *data;
1495 + struct stmmac_resources stmmac_res;
1496 struct sti_dwmac *dwmac;
1497 int ret;
1498
1499 + data = of_device_get_match_data(&pdev->dev);
1500 + if (!data) {
1501 + dev_err(&pdev->dev, "No OF match data provided\n");
1502 + return -EINVAL;
1503 + }
1504 +
1505 + ret = stmmac_get_platform_resources(pdev, &stmmac_res);
1506 + if (ret)
1507 + return ret;
1508 +
1509 + plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
1510 + if (IS_ERR(plat_dat))
1511 + return PTR_ERR(plat_dat);
1512 +
1513 dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
1514 if (!dwmac)
1515 - return ERR_PTR(-ENOMEM);
1516 + return -ENOMEM;
1517
1518 ret = sti_dwmac_parse_data(dwmac, pdev);
1519 if (ret) {
1520 dev_err(&pdev->dev, "Unable to parse OF data\n");
1521 - return ERR_PTR(ret);
1522 + return ret;
1523 }
1524
1525 - return dwmac;
1526 + dwmac->fix_retime_src = data->fix_retime_src;
1527 +
1528 + plat_dat->bsp_priv = dwmac;
1529 + plat_dat->init = sti_dwmac_init;
1530 + plat_dat->exit = sti_dwmac_exit;
1531 + plat_dat->fix_mac_speed = data->fix_retime_src;
1532 +
1533 + ret = sti_dwmac_init(pdev, plat_dat->bsp_priv);
1534 + if (ret)
1535 + return ret;
1536 +
1537 + return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
1538 }
1539
1540 -const struct stmmac_of_data stih4xx_dwmac_data = {
1541 - .fix_mac_speed = stih4xx_fix_retime_src,
1542 - .setup = sti_dwmac_setup,
1543 - .init = stix4xx_init,
1544 - .exit = sti_dwmac_exit,
1545 +static const struct sti_dwmac_of_data stih4xx_dwmac_data = {
1546 + .fix_retime_src = stih4xx_fix_retime_src,
1547 +};
1548 +
1549 +static const struct sti_dwmac_of_data stid127_dwmac_data = {
1550 + .fix_retime_src = stid127_fix_retime_src,
1551 };
1552
1553 -const struct stmmac_of_data stid127_dwmac_data = {
1554 - .fix_mac_speed = stid127_fix_retime_src,
1555 - .setup = sti_dwmac_setup,
1556 - .init = stid127_init,
1557 - .exit = sti_dwmac_exit,
1558 +static const struct of_device_id sti_dwmac_match[] = {
1559 + { .compatible = "st,stih415-dwmac", .data = &stih4xx_dwmac_data},
1560 + { .compatible = "st,stih416-dwmac", .data = &stih4xx_dwmac_data},
1561 + { .compatible = "st,stid127-dwmac", .data = &stid127_dwmac_data},
1562 + { .compatible = "st,stih407-dwmac", .data = &stih4xx_dwmac_data},
1563 + { }
1564 };
1565 +MODULE_DEVICE_TABLE(of, sti_dwmac_match);
1566 +
1567 +static struct platform_driver sti_dwmac_driver = {
1568 + .probe = sti_dwmac_probe,
1569 + .remove = stmmac_pltfr_remove,
1570 + .driver = {
1571 + .name = "sti-dwmac",
1572 + .pm = &stmmac_pltfr_pm_ops,
1573 + .of_match_table = sti_dwmac_match,
1574 + },
1575 +};
1576 +module_platform_driver(sti_dwmac_driver);
1577 +
1578 +MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@st.com>");
1579 +MODULE_DESCRIPTION("STMicroelectronics DWMAC Specific Glue layer");
1580 +MODULE_LICENSE("GPL");
1581 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
1582 +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c
1583 @@ -18,7 +18,9 @@
1584
1585 #include <linux/stmmac.h>
1586 #include <linux/clk.h>
1587 +#include <linux/module.h>
1588 #include <linux/phy.h>
1589 +#include <linux/platform_device.h>
1590 #include <linux/of_net.h>
1591 #include <linux/regulator/consumer.h>
1592
1593 @@ -31,35 +33,6 @@ struct sunxi_priv_data {
1594 struct regulator *regulator;
1595 };
1596
1597 -static void *sun7i_gmac_setup(struct platform_device *pdev)
1598 -{
1599 - struct sunxi_priv_data *gmac;
1600 - struct device *dev = &pdev->dev;
1601 -
1602 - gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
1603 - if (!gmac)
1604 - return ERR_PTR(-ENOMEM);
1605 -
1606 - gmac->interface = of_get_phy_mode(dev->of_node);
1607 -
1608 - gmac->tx_clk = devm_clk_get(dev, "allwinner_gmac_tx");
1609 - if (IS_ERR(gmac->tx_clk)) {
1610 - dev_err(dev, "could not get tx clock\n");
1611 - return gmac->tx_clk;
1612 - }
1613 -
1614 - /* Optional regulator for PHY */
1615 - gmac->regulator = devm_regulator_get_optional(dev, "phy");
1616 - if (IS_ERR(gmac->regulator)) {
1617 - if (PTR_ERR(gmac->regulator) == -EPROBE_DEFER)
1618 - return ERR_PTR(-EPROBE_DEFER);
1619 - dev_info(dev, "no regulator found\n");
1620 - gmac->regulator = NULL;
1621 - }
1622 -
1623 - return gmac;
1624 -}
1625 -
1626 #define SUN7I_GMAC_GMII_RGMII_RATE 125000000
1627 #define SUN7I_GMAC_MII_RATE 25000000
1628
1629 @@ -130,13 +103,76 @@ static void sun7i_fix_speed(void *priv,
1630 }
1631 }
1632
1633 -/* of_data specifying hardware features and callbacks.
1634 - * hardware features were copied from Allwinner drivers. */
1635 -const struct stmmac_of_data sun7i_gmac_data = {
1636 - .has_gmac = 1,
1637 - .tx_coe = 1,
1638 - .fix_mac_speed = sun7i_fix_speed,
1639 - .setup = sun7i_gmac_setup,
1640 - .init = sun7i_gmac_init,
1641 - .exit = sun7i_gmac_exit,
1642 +static int sun7i_gmac_probe(struct platform_device *pdev)
1643 +{
1644 + struct plat_stmmacenet_data *plat_dat;
1645 + struct stmmac_resources stmmac_res;
1646 + struct sunxi_priv_data *gmac;
1647 + struct device *dev = &pdev->dev;
1648 + int ret;
1649 +
1650 + ret = stmmac_get_platform_resources(pdev, &stmmac_res);
1651 + if (ret)
1652 + return ret;
1653 +
1654 + plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
1655 + if (IS_ERR(plat_dat))
1656 + return PTR_ERR(plat_dat);
1657 +
1658 + gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
1659 + if (!gmac)
1660 + return -ENOMEM;
1661 +
1662 + gmac->interface = of_get_phy_mode(dev->of_node);
1663 +
1664 + gmac->tx_clk = devm_clk_get(dev, "allwinner_gmac_tx");
1665 + if (IS_ERR(gmac->tx_clk)) {
1666 + dev_err(dev, "could not get tx clock\n");
1667 + return PTR_ERR(gmac->tx_clk);
1668 + }
1669 +
1670 + /* Optional regulator for PHY */
1671 + gmac->regulator = devm_regulator_get_optional(dev, "phy");
1672 + if (IS_ERR(gmac->regulator)) {
1673 + if (PTR_ERR(gmac->regulator) == -EPROBE_DEFER)
1674 + return -EPROBE_DEFER;
1675 + dev_info(dev, "no regulator found\n");
1676 + gmac->regulator = NULL;
1677 + }
1678 +
1679 + /* platform data specifying hardware features and callbacks.
1680 + * hardware features were copied from Allwinner drivers. */
1681 + plat_dat->tx_coe = 1;
1682 + plat_dat->has_gmac = true;
1683 + plat_dat->bsp_priv = gmac;
1684 + plat_dat->init = sun7i_gmac_init;
1685 + plat_dat->exit = sun7i_gmac_exit;
1686 + plat_dat->fix_mac_speed = sun7i_fix_speed;
1687 +
1688 + ret = sun7i_gmac_init(pdev, plat_dat->bsp_priv);
1689 + if (ret)
1690 + return ret;
1691 +
1692 + return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
1693 +}
1694 +
1695 +static const struct of_device_id sun7i_dwmac_match[] = {
1696 + { .compatible = "allwinner,sun7i-a20-gmac" },
1697 + { }
1698 };
1699 +MODULE_DEVICE_TABLE(of, sun7i_dwmac_match);
1700 +
1701 +static struct platform_driver sun7i_dwmac_driver = {
1702 + .probe = sun7i_gmac_probe,
1703 + .remove = stmmac_pltfr_remove,
1704 + .driver = {
1705 + .name = "sun7i-dwmac",
1706 + .pm = &stmmac_pltfr_pm_ops,
1707 + .of_match_table = sun7i_dwmac_match,
1708 + },
1709 +};
1710 +module_platform_driver(sun7i_dwmac_driver);
1711 +
1712 +MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
1713 +MODULE_DESCRIPTION("Allwinner sunxi DWMAC specific glue layer");
1714 +MODULE_LICENSE("GPL");
1715 --- a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
1716 +++ b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
1717 @@ -73,7 +73,7 @@
1718 #define MMC_RX_OCTETCOUNT_G 0x00000188
1719 #define MMC_RX_BROADCASTFRAME_G 0x0000018c
1720 #define MMC_RX_MULTICASTFRAME_G 0x00000190
1721 -#define MMC_RX_CRC_ERRROR 0x00000194
1722 +#define MMC_RX_CRC_ERROR 0x00000194
1723 #define MMC_RX_ALIGN_ERROR 0x00000198
1724 #define MMC_RX_RUN_ERROR 0x0000019C
1725 #define MMC_RX_JABBER_ERROR 0x000001A0
1726 @@ -196,7 +196,7 @@ void dwmac_mmc_read(void __iomem *ioaddr
1727 mmc->mmc_rx_octetcount_g += readl(ioaddr + MMC_RX_OCTETCOUNT_G);
1728 mmc->mmc_rx_broadcastframe_g += readl(ioaddr + MMC_RX_BROADCASTFRAME_G);
1729 mmc->mmc_rx_multicastframe_g += readl(ioaddr + MMC_RX_MULTICASTFRAME_G);
1730 - mmc->mmc_rx_crc_error += readl(ioaddr + MMC_RX_CRC_ERRROR);
1731 + mmc->mmc_rx_crc_error += readl(ioaddr + MMC_RX_CRC_ERROR);
1732 mmc->mmc_rx_align_error += readl(ioaddr + MMC_RX_ALIGN_ERROR);
1733 mmc->mmc_rx_run_error += readl(ioaddr + MMC_RX_RUN_ERROR);
1734 mmc->mmc_rx_jabber_error += readl(ioaddr + MMC_RX_JABBER_ERROR);
1735 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
1736 +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
1737 @@ -34,6 +34,14 @@
1738 #include <linux/ptp_clock_kernel.h>
1739 #include <linux/reset.h>
1740
1741 +struct stmmac_resources {
1742 + void __iomem *addr;
1743 + const char *mac;
1744 + int wol_irq;
1745 + int lpi_irq;
1746 + int irq;
1747 +};
1748 +
1749 struct stmmac_tx_info {
1750 dma_addr_t buf;
1751 bool map_as_page;
1752 @@ -135,9 +143,9 @@ void stmmac_ptp_unregister(struct stmmac
1753 int stmmac_resume(struct net_device *ndev);
1754 int stmmac_suspend(struct net_device *ndev);
1755 int stmmac_dvr_remove(struct net_device *ndev);
1756 -struct stmmac_priv *stmmac_dvr_probe(struct device *device,
1757 - struct plat_stmmacenet_data *plat_dat,
1758 - void __iomem *addr);
1759 +int stmmac_dvr_probe(struct device *device,
1760 + struct plat_stmmacenet_data *plat_dat,
1761 + struct stmmac_resources *res);
1762 void stmmac_disable_eee_mode(struct stmmac_priv *priv);
1763 bool stmmac_eee_init(struct stmmac_priv *priv);
1764
1765 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
1766 +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
1767 @@ -52,6 +52,7 @@
1768 #include "stmmac_ptp.h"
1769 #include "stmmac.h"
1770 #include <linux/reset.h>
1771 +#include <linux/of_mdio.h>
1772
1773 #define STMMAC_ALIGN(x) L1_CACHE_ALIGN(x)
1774
1775 @@ -816,18 +817,25 @@ static int stmmac_init_phy(struct net_de
1776 priv->speed = 0;
1777 priv->oldduplex = -1;
1778
1779 - if (priv->plat->phy_bus_name)
1780 - snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
1781 - priv->plat->phy_bus_name, priv->plat->bus_id);
1782 - else
1783 - snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
1784 - priv->plat->bus_id);
1785 + if (priv->plat->phy_node) {
1786 + phydev = of_phy_connect(dev, priv->plat->phy_node,
1787 + &stmmac_adjust_link, 0, interface);
1788 + } else {
1789 + if (priv->plat->phy_bus_name)
1790 + snprintf(bus_id, MII_BUS_ID_SIZE, "%s-%x",
1791 + priv->plat->phy_bus_name, priv->plat->bus_id);
1792 + else
1793 + snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x",
1794 + priv->plat->bus_id);
1795
1796 - snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
1797 - priv->plat->phy_addr);
1798 - pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id_fmt);
1799 + snprintf(phy_id_fmt, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
1800 + priv->plat->phy_addr);
1801 + pr_debug("stmmac_init_phy: trying to attach to %s\n",
1802 + phy_id_fmt);
1803
1804 - phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link, interface);
1805 + phydev = phy_connect(dev, phy_id_fmt, &stmmac_adjust_link,
1806 + interface);
1807 + }
1808
1809 if (IS_ERR_OR_NULL(phydev)) {
1810 pr_err("%s: Could not attach to PHY\n", dev->name);
1811 @@ -851,7 +859,7 @@ static int stmmac_init_phy(struct net_de
1812 * device as well.
1813 * Note: phydev->phy_id is the result of reading the UID PHY registers.
1814 */
1815 - if (phydev->phy_id == 0) {
1816 + if (!priv->plat->phy_node && phydev->phy_id == 0) {
1817 phy_disconnect(phydev);
1818 return -ENODEV;
1819 }
1820 @@ -978,13 +986,11 @@ static int stmmac_init_rx_buffers(struct
1821 {
1822 struct sk_buff *skb;
1823
1824 - skb = __netdev_alloc_skb(priv->dev, priv->dma_buf_sz + NET_IP_ALIGN,
1825 - flags);
1826 + skb = __netdev_alloc_skb_ip_align(priv->dev, priv->dma_buf_sz, flags);
1827 if (!skb) {
1828 pr_err("%s: Rx init fails; skb is NULL\n", __func__);
1829 return -ENOMEM;
1830 }
1831 - skb_reserve(skb, NET_IP_ALIGN);
1832 priv->rx_skbuff[i] = skb;
1833 priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data,
1834 priv->dma_buf_sz,
1835 @@ -2803,16 +2809,15 @@ static int stmmac_hw_init(struct stmmac_
1836 * stmmac_dvr_probe
1837 * @device: device pointer
1838 * @plat_dat: platform data pointer
1839 - * @addr: iobase memory address
1840 + * @res: stmmac resource pointer
1841 * Description: this is the main probe function used to
1842 * call the alloc_etherdev, allocate the priv structure.
1843 * Return:
1844 - * on success the new private structure is returned, otherwise the error
1845 - * pointer.
1846 + * returns 0 on success, otherwise errno.
1847 */
1848 -struct stmmac_priv *stmmac_dvr_probe(struct device *device,
1849 - struct plat_stmmacenet_data *plat_dat,
1850 - void __iomem *addr)
1851 +int stmmac_dvr_probe(struct device *device,
1852 + struct plat_stmmacenet_data *plat_dat,
1853 + struct stmmac_resources *res)
1854 {
1855 int ret = 0;
1856 struct net_device *ndev = NULL;
1857 @@ -2820,7 +2825,7 @@ struct stmmac_priv *stmmac_dvr_probe(str
1858
1859 ndev = alloc_etherdev(sizeof(struct stmmac_priv));
1860 if (!ndev)
1861 - return ERR_PTR(-ENOMEM);
1862 + return -ENOMEM;
1863
1864 SET_NETDEV_DEV(ndev, device);
1865
1866 @@ -2831,8 +2836,17 @@ struct stmmac_priv *stmmac_dvr_probe(str
1867 stmmac_set_ethtool_ops(ndev);
1868 priv->pause = pause;
1869 priv->plat = plat_dat;
1870 - priv->ioaddr = addr;
1871 - priv->dev->base_addr = (unsigned long)addr;
1872 + priv->ioaddr = res->addr;
1873 + priv->dev->base_addr = (unsigned long)res->addr;
1874 +
1875 + priv->dev->irq = res->irq;
1876 + priv->wol_irq = res->wol_irq;
1877 + priv->lpi_irq = res->lpi_irq;
1878 +
1879 + if (res->mac)
1880 + memcpy(priv->dev->dev_addr, res->mac, ETH_ALEN);
1881 +
1882 + dev_set_drvdata(device, priv->dev);
1883
1884 /* Verify driver arguments */
1885 stmmac_verify_args();
1886 @@ -2947,7 +2961,7 @@ struct stmmac_priv *stmmac_dvr_probe(str
1887 }
1888 }
1889
1890 - return priv;
1891 + return 0;
1892
1893 error_mdio_register:
1894 unregister_netdev(ndev);
1895 @@ -2960,7 +2974,7 @@ error_pclk_get:
1896 error_clk_get:
1897 free_netdev(ndev);
1898
1899 - return ERR_PTR(ret);
1900 + return ret;
1901 }
1902 EXPORT_SYMBOL_GPL(stmmac_dvr_probe);
1903
1904 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
1905 +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
1906 @@ -161,11 +161,16 @@ int stmmac_mdio_reset(struct mii_bus *bu
1907
1908 if (!gpio_request(reset_gpio, "mdio-reset")) {
1909 gpio_direction_output(reset_gpio, active_low ? 1 : 0);
1910 - udelay(data->delays[0]);
1911 + if (data->delays[0])
1912 + msleep(DIV_ROUND_UP(data->delays[0], 1000));
1913 +
1914 gpio_set_value(reset_gpio, active_low ? 0 : 1);
1915 - udelay(data->delays[1]);
1916 + if (data->delays[1])
1917 + msleep(DIV_ROUND_UP(data->delays[1], 1000));
1918 +
1919 gpio_set_value(reset_gpio, active_low ? 1 : 0);
1920 - udelay(data->delays[2]);
1921 + if (data->delays[2])
1922 + msleep(DIV_ROUND_UP(data->delays[2], 1000));
1923 }
1924 }
1925 #endif
1926 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
1927 +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
1928 @@ -163,7 +163,7 @@ static int stmmac_pci_probe(struct pci_d
1929 {
1930 struct stmmac_pci_info *info = (struct stmmac_pci_info *)id->driver_data;
1931 struct plat_stmmacenet_data *plat;
1932 - struct stmmac_priv *priv;
1933 + struct stmmac_resources res;
1934 int i;
1935 int ret;
1936
1937 @@ -214,19 +214,12 @@ static int stmmac_pci_probe(struct pci_d
1938
1939 pci_enable_msi(pdev);
1940
1941 - priv = stmmac_dvr_probe(&pdev->dev, plat, pcim_iomap_table(pdev)[i]);
1942 - if (IS_ERR(priv)) {
1943 - dev_err(&pdev->dev, "%s: main driver probe failed\n", __func__);
1944 - return PTR_ERR(priv);
1945 - }
1946 - priv->dev->irq = pdev->irq;
1947 - priv->wol_irq = pdev->irq;
1948 -
1949 - pci_set_drvdata(pdev, priv->dev);
1950 -
1951 - dev_dbg(&pdev->dev, "STMMAC PCI driver registration completed\n");
1952 + memset(&res, 0, sizeof(res));
1953 + res.addr = pcim_iomap_table(pdev)[i];
1954 + res.wol_irq = pdev->irq;
1955 + res.irq = pdev->irq;
1956
1957 - return 0;
1958 + return stmmac_dvr_probe(&pdev->dev, plat, &res);
1959 }
1960
1961 /**
1962 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
1963 +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
1964 @@ -28,29 +28,11 @@
1965 #include <linux/of.h>
1966 #include <linux/of_net.h>
1967 #include <linux/of_device.h>
1968 +#include <linux/of_mdio.h>
1969
1970 #include "stmmac.h"
1971 #include "stmmac_platform.h"
1972
1973 -static const struct of_device_id stmmac_dt_ids[] = {
1974 - /* SoC specific glue layers should come before generic bindings */
1975 - { .compatible = "rockchip,rk3288-gmac", .data = &rk3288_gmac_data},
1976 - { .compatible = "amlogic,meson6-dwmac", .data = &meson6_dwmac_data},
1977 - { .compatible = "allwinner,sun7i-a20-gmac", .data = &sun7i_gmac_data},
1978 - { .compatible = "st,stih415-dwmac", .data = &stih4xx_dwmac_data},
1979 - { .compatible = "st,stih416-dwmac", .data = &stih4xx_dwmac_data},
1980 - { .compatible = "st,stid127-dwmac", .data = &stid127_dwmac_data},
1981 - { .compatible = "st,stih407-dwmac", .data = &stih4xx_dwmac_data},
1982 - { .compatible = "altr,socfpga-stmmac", .data = &socfpga_gmac_data },
1983 - { .compatible = "st,spear600-gmac"},
1984 - { .compatible = "snps,dwmac-3.610"},
1985 - { .compatible = "snps,dwmac-3.70a"},
1986 - { .compatible = "snps,dwmac-3.710"},
1987 - { .compatible = "snps,dwmac"},
1988 - { /* sentinel */ }
1989 -};
1990 -MODULE_DEVICE_TABLE(of, stmmac_dt_ids);
1991 -
1992 #ifdef CONFIG_OF
1993
1994 /**
1995 @@ -122,37 +104,16 @@ static int dwmac1000_validate_ucast_entr
1996 * this function is to read the driver parameters from device-tree and
1997 * set some private fields that will be used by the main at runtime.
1998 */
1999 -static int stmmac_probe_config_dt(struct platform_device *pdev,
2000 - struct plat_stmmacenet_data *plat,
2001 - const char **mac)
2002 +struct plat_stmmacenet_data *
2003 +stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
2004 {
2005 struct device_node *np = pdev->dev.of_node;
2006 + struct plat_stmmacenet_data *plat;
2007 struct stmmac_dma_cfg *dma_cfg;
2008 - const struct of_device_id *device;
2009 -
2010 - if (!np)
2011 - return -ENODEV;
2012
2013 - device = of_match_device(stmmac_dt_ids, &pdev->dev);
2014 - if (!device)
2015 - return -ENODEV;
2016 -
2017 - if (device->data) {
2018 - const struct stmmac_of_data *data = device->data;
2019 - plat->has_gmac = data->has_gmac;
2020 - plat->enh_desc = data->enh_desc;
2021 - plat->tx_coe = data->tx_coe;
2022 - plat->rx_coe = data->rx_coe;
2023 - plat->bugged_jumbo = data->bugged_jumbo;
2024 - plat->pmt = data->pmt;
2025 - plat->riwt_off = data->riwt_off;
2026 - plat->fix_mac_speed = data->fix_mac_speed;
2027 - plat->bus_setup = data->bus_setup;
2028 - plat->setup = data->setup;
2029 - plat->free = data->free;
2030 - plat->init = data->init;
2031 - plat->exit = data->exit;
2032 - }
2033 + plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL);
2034 + if (!plat)
2035 + return ERR_PTR(-ENOMEM);
2036
2037 *mac = of_get_mac_address(np);
2038 plat->interface = of_get_phy_mode(np);
2039 @@ -168,13 +129,24 @@ static int stmmac_probe_config_dt(struct
2040 /* Default to phy auto-detection */
2041 plat->phy_addr = -1;
2042
2043 + /* If we find a phy-handle property, use it as the PHY */
2044 + plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
2045 +
2046 + /* If phy-handle is not specified, check if we have a fixed-phy */
2047 + if (!plat->phy_node && of_phy_is_fixed_link(np)) {
2048 + if ((of_phy_register_fixed_link(np) < 0))
2049 + return ERR_PTR(-ENODEV);
2050 +
2051 + plat->phy_node = of_node_get(np);
2052 + }
2053 +
2054 /* "snps,phy-addr" is not a standard property. Mark it as deprecated
2055 * and warn of its use. Remove this when phy node support is added.
2056 */
2057 if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0)
2058 dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n");
2059
2060 - if (plat->phy_bus_name)
2061 + if (plat->phy_node || plat->phy_bus_name)
2062 plat->mdio_bus_data = NULL;
2063 else
2064 plat->mdio_bus_data =
2065 @@ -194,6 +166,12 @@ static int stmmac_probe_config_dt(struct
2066 */
2067 plat->maxmtu = JUMBO_LEN;
2068
2069 + /* Set default value for multicast hash bins */
2070 + plat->multicast_filter_bins = HASH_TABLE_SIZE;
2071 +
2072 + /* Set default value for unicast filter entries */
2073 + plat->unicast_filter_entries = 1;
2074 +
2075 /*
2076 * Currently only the properties needed on SPEAr600
2077 * are provided. All other properties should be added
2078 @@ -232,8 +210,10 @@ static int stmmac_probe_config_dt(struct
2079 if (of_find_property(np, "snps,pbl", NULL)) {
2080 dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
2081 GFP_KERNEL);
2082 - if (!dma_cfg)
2083 - return -ENOMEM;
2084 + if (!dma_cfg) {
2085 + of_node_put(np);
2086 + return ERR_PTR(-ENOMEM);
2087 + }
2088 plat->dma_cfg = dma_cfg;
2089 of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
2090 dma_cfg->fixed_burst =
2091 @@ -250,45 +230,34 @@ static int stmmac_probe_config_dt(struct
2092 pr_warn("force_sf_dma_mode is ignored if force_thresh_dma_mode is set.");
2093 }
2094
2095 - return 0;
2096 + return plat;
2097 }
2098 #else
2099 -static int stmmac_probe_config_dt(struct platform_device *pdev,
2100 - struct plat_stmmacenet_data *plat,
2101 - const char **mac)
2102 +struct plat_stmmacenet_data *
2103 +stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
2104 {
2105 - return -ENOSYS;
2106 + return ERR_PTR(-ENOSYS);
2107 }
2108 #endif /* CONFIG_OF */
2109 +EXPORT_SYMBOL_GPL(stmmac_probe_config_dt);
2110
2111 -/**
2112 - * stmmac_pltfr_probe - platform driver probe.
2113 - * @pdev: platform device pointer
2114 - * Description: platform_device probe function. It is to allocate
2115 - * the necessary platform resources, invoke custom helper (if required) and
2116 - * invoke the main probe function.
2117 - */
2118 -static int stmmac_pltfr_probe(struct platform_device *pdev)
2119 +int stmmac_get_platform_resources(struct platform_device *pdev,
2120 + struct stmmac_resources *stmmac_res)
2121 {
2122 - int ret = 0;
2123 struct resource *res;
2124 - struct device *dev = &pdev->dev;
2125 - void __iomem *addr = NULL;
2126 - struct stmmac_priv *priv = NULL;
2127 - struct plat_stmmacenet_data *plat_dat = NULL;
2128 - const char *mac = NULL;
2129 - int irq, wol_irq, lpi_irq;
2130 +
2131 + memset(stmmac_res, 0, sizeof(*stmmac_res));
2132
2133 /* Get IRQ information early to have an ability to ask for deferred
2134 * probe if needed before we went too far with resource allocation.
2135 */
2136 - irq = platform_get_irq_byname(pdev, "macirq");
2137 - if (irq < 0) {
2138 - if (irq != -EPROBE_DEFER) {
2139 - dev_err(dev,
2140 + stmmac_res->irq = platform_get_irq_byname(pdev, "macirq");
2141 + if (stmmac_res->irq < 0) {
2142 + if (stmmac_res->irq != -EPROBE_DEFER) {
2143 + dev_err(&pdev->dev,
2144 "MAC IRQ configuration information not found\n");
2145 }
2146 - return irq;
2147 + return stmmac_res->irq;
2148 }
2149
2150 /* On some platforms e.g. SPEAr the wake up irq differs from the mac irq
2151 @@ -298,82 +267,23 @@ static int stmmac_pltfr_probe(struct pla
2152 * In case the wake up interrupt is not passed from the platform
2153 * so the driver will continue to use the mac irq (ndev->irq)
2154 */
2155 - wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq");
2156 - if (wol_irq < 0) {
2157 - if (wol_irq == -EPROBE_DEFER)
2158 + stmmac_res->wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq");
2159 + if (stmmac_res->wol_irq < 0) {
2160 + if (stmmac_res->wol_irq == -EPROBE_DEFER)
2161 return -EPROBE_DEFER;
2162 - wol_irq = irq;
2163 + stmmac_res->wol_irq = stmmac_res->irq;
2164 }
2165
2166 - lpi_irq = platform_get_irq_byname(pdev, "eth_lpi");
2167 - if (lpi_irq == -EPROBE_DEFER)
2168 + stmmac_res->lpi_irq = platform_get_irq_byname(pdev, "eth_lpi");
2169 + if (stmmac_res->lpi_irq == -EPROBE_DEFER)
2170 return -EPROBE_DEFER;
2171
2172 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2173 - addr = devm_ioremap_resource(dev, res);
2174 - if (IS_ERR(addr))
2175 - return PTR_ERR(addr);
2176 -
2177 - plat_dat = dev_get_platdata(&pdev->dev);
2178 -
2179 - if (!plat_dat)
2180 - plat_dat = devm_kzalloc(&pdev->dev,
2181 - sizeof(struct plat_stmmacenet_data),
2182 - GFP_KERNEL);
2183 - if (!plat_dat) {
2184 - pr_err("%s: ERROR: no memory", __func__);
2185 - return -ENOMEM;
2186 - }
2187 -
2188 - /* Set default value for multicast hash bins */
2189 - plat_dat->multicast_filter_bins = HASH_TABLE_SIZE;
2190 + stmmac_res->addr = devm_ioremap_resource(&pdev->dev, res);
2191
2192 - /* Set default value for unicast filter entries */
2193 - plat_dat->unicast_filter_entries = 1;
2194 -
2195 - if (pdev->dev.of_node) {
2196 - ret = stmmac_probe_config_dt(pdev, plat_dat, &mac);
2197 - if (ret) {
2198 - pr_err("%s: main dt probe failed", __func__);
2199 - return ret;
2200 - }
2201 - }
2202 -
2203 - /* Custom setup (if needed) */
2204 - if (plat_dat->setup) {
2205 - plat_dat->bsp_priv = plat_dat->setup(pdev);
2206 - if (IS_ERR(plat_dat->bsp_priv))
2207 - return PTR_ERR(plat_dat->bsp_priv);
2208 - }
2209 -
2210 - /* Custom initialisation (if needed)*/
2211 - if (plat_dat->init) {
2212 - ret = plat_dat->init(pdev, plat_dat->bsp_priv);
2213 - if (unlikely(ret))
2214 - return ret;
2215 - }
2216 -
2217 - priv = stmmac_dvr_probe(&(pdev->dev), plat_dat, addr);
2218 - if (IS_ERR(priv)) {
2219 - pr_err("%s: main driver probe failed", __func__);
2220 - return PTR_ERR(priv);
2221 - }
2222 -
2223 - /* Copy IRQ values to priv structure which is now avaialble */
2224 - priv->dev->irq = irq;
2225 - priv->wol_irq = wol_irq;
2226 - priv->lpi_irq = lpi_irq;
2227 -
2228 - /* Get MAC address if available (DT) */
2229 - if (mac)
2230 - memcpy(priv->dev->dev_addr, mac, ETH_ALEN);
2231 -
2232 - platform_set_drvdata(pdev, priv->dev);
2233 -
2234 - pr_debug("STMMAC platform driver registration completed");
2235 -
2236 - return 0;
2237 + return PTR_ERR_OR_ZERO(stmmac_res->addr);
2238 }
2239 +EXPORT_SYMBOL_GPL(stmmac_get_platform_resources);
2240
2241 /**
2242 * stmmac_pltfr_remove
2243 @@ -381,7 +291,7 @@ static int stmmac_pltfr_probe(struct pla
2244 * Description: this function calls the main to free the net resources
2245 * and calls the platforms hook and release the resources (e.g. mem).
2246 */
2247 -static int stmmac_pltfr_remove(struct platform_device *pdev)
2248 +int stmmac_pltfr_remove(struct platform_device *pdev)
2249 {
2250 struct net_device *ndev = platform_get_drvdata(pdev);
2251 struct stmmac_priv *priv = netdev_priv(ndev);
2252 @@ -390,11 +300,9 @@ static int stmmac_pltfr_remove(struct pl
2253 if (priv->plat->exit)
2254 priv->plat->exit(pdev, priv->plat->bsp_priv);
2255
2256 - if (priv->plat->free)
2257 - priv->plat->free(pdev, priv->plat->bsp_priv);
2258 -
2259 return ret;
2260 }
2261 +EXPORT_SYMBOL_GPL(stmmac_pltfr_remove);
2262
2263 #ifdef CONFIG_PM_SLEEP
2264 /**
2265 @@ -438,21 +346,10 @@ static int stmmac_pltfr_resume(struct de
2266 }
2267 #endif /* CONFIG_PM_SLEEP */
2268
2269 -static SIMPLE_DEV_PM_OPS(stmmac_pltfr_pm_ops,
2270 - stmmac_pltfr_suspend, stmmac_pltfr_resume);
2271 -
2272 -static struct platform_driver stmmac_pltfr_driver = {
2273 - .probe = stmmac_pltfr_probe,
2274 - .remove = stmmac_pltfr_remove,
2275 - .driver = {
2276 - .name = STMMAC_RESOURCE_NAME,
2277 - .pm = &stmmac_pltfr_pm_ops,
2278 - .of_match_table = of_match_ptr(stmmac_dt_ids),
2279 - },
2280 -};
2281 -
2282 -module_platform_driver(stmmac_pltfr_driver);
2283 +SIMPLE_DEV_PM_OPS(stmmac_pltfr_pm_ops, stmmac_pltfr_suspend,
2284 + stmmac_pltfr_resume);
2285 +EXPORT_SYMBOL_GPL(stmmac_pltfr_pm_ops);
2286
2287 -MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet PLATFORM driver");
2288 +MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet platform support");
2289 MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
2290 MODULE_LICENSE("GPL");
2291 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
2292 +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.h
2293 @@ -19,11 +19,15 @@
2294 #ifndef __STMMAC_PLATFORM_H__
2295 #define __STMMAC_PLATFORM_H__
2296
2297 -extern const struct stmmac_of_data meson6_dwmac_data;
2298 -extern const struct stmmac_of_data sun7i_gmac_data;
2299 -extern const struct stmmac_of_data stih4xx_dwmac_data;
2300 -extern const struct stmmac_of_data stid127_dwmac_data;
2301 -extern const struct stmmac_of_data socfpga_gmac_data;
2302 -extern const struct stmmac_of_data rk3288_gmac_data;
2303 +#include "stmmac.h"
2304 +
2305 +struct plat_stmmacenet_data *
2306 +stmmac_probe_config_dt(struct platform_device *pdev, const char **mac);
2307 +
2308 +int stmmac_get_platform_resources(struct platform_device *pdev,
2309 + struct stmmac_resources *stmmac_res);
2310 +
2311 +int stmmac_pltfr_remove(struct platform_device *pdev);
2312 +extern const struct dev_pm_ops stmmac_pltfr_pm_ops;
2313
2314 #endif /* __STMMAC_PLATFORM_H__ */
2315 --- a/include/linux/stmmac.h
2316 +++ b/include/linux/stmmac.h
2317 @@ -99,6 +99,7 @@ struct plat_stmmacenet_data {
2318 int phy_addr;
2319 int interface;
2320 struct stmmac_mdio_bus_data *mdio_bus_data;
2321 + struct device_node *phy_node;
2322 struct stmmac_dma_cfg *dma_cfg;
2323 int clk_csr;
2324 int has_gmac;
2325 @@ -118,30 +119,8 @@ struct plat_stmmacenet_data {
2326 int rx_fifo_size;
2327 void (*fix_mac_speed)(void *priv, unsigned int speed);
2328 void (*bus_setup)(void __iomem *ioaddr);
2329 - void *(*setup)(struct platform_device *pdev);
2330 - void (*free)(struct platform_device *pdev, void *priv);
2331 int (*init)(struct platform_device *pdev, void *priv);
2332 void (*exit)(struct platform_device *pdev, void *priv);
2333 - void *custom_cfg;
2334 - void *custom_data;
2335 void *bsp_priv;
2336 };
2337 -
2338 -/* of_data for SoC glue layer device tree bindings */
2339 -
2340 -struct stmmac_of_data {
2341 - int has_gmac;
2342 - int enh_desc;
2343 - int tx_coe;
2344 - int rx_coe;
2345 - int bugged_jumbo;
2346 - int pmt;
2347 - int riwt_off;
2348 - void (*fix_mac_speed)(void *priv, unsigned int speed);
2349 - void (*bus_setup)(void __iomem *ioaddr);
2350 - void *(*setup)(struct platform_device *pdev);
2351 - void (*free)(struct platform_device *pdev, void *priv);
2352 - int (*init)(struct platform_device *pdev, void *priv);
2353 - void (*exit)(struct platform_device *pdev, void *priv);
2354 -};
2355 #endif