aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2014-03-17 05:26:40 -0400
committerArnd Bergmann <arnd@arndb.de>2014-03-17 05:26:40 -0400
commitde65ded49e95dbbd685b613a615f6821868e5b33 (patch)
tree3bfd84f248722ab357fd748723bace6e5603c554
parenta929478f6720ac15d949117188cd6798b4a9c286 (diff)
parenta5d6ac2a84a393a7142f9cafe15ade9aa94b6b42 (diff)
Merge tag 'socfpga_updates_for_3.15_v2' of git://git.rocketboards.org/linux-socfpga-next into next/drivers
Merge "SOCFPGA updates for 3.15 version 2" from Dinh Nguyen: *Update SOCFPGA DTS to include ethernet, sd/mmc, and clock fixes *Add stmmac ethernet glue layer *Update socfpga_defconfig to include sd/mmc, and micrel_phy * tag 'socfpga_updates_for_3.15_v2' of git://git.rocketboards.org/linux-socfpga-next: dts: socfpga: Add sysmgr node so the gmac can use to reference dts: socfpga: Add support for SD/MMC on the SOCFPGA platform dts: socfpga: Update clock entry to support multiple parents ARM: socfpga: Update socfpga_defconfig dts: socfpga: Add DTS entry for adding the stmmac glue layer for stmmac. net: stmmac: Add SOCFPGA glue driver Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-rw-r--r--Documentation/devicetree/bindings/mmc/socfpga-dw-mshc.txt23
-rw-r--r--Documentation/devicetree/bindings/net/socfpga-dwmac.txt35
-rw-r--r--arch/arm/boot/dts/socfpga.dtsi87
-rw-r--r--arch/arm/boot/dts/socfpga_arria5.dtsi11
-rw-r--r--arch/arm/boot/dts/socfpga_arria5_socdk.dts24
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5.dtsi11
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5_socdk.dts17
-rw-r--r--arch/arm/boot/dts/socfpga_cyclone5_sockit.dts22
-rw-r--r--arch/arm/boot/dts/socfpga_vt.dts19
-rw-r--r--arch/arm/configs/socfpga_defconfig6
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/Makefile1
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c183
12 files changed, 413 insertions, 26 deletions
diff --git a/Documentation/devicetree/bindings/mmc/socfpga-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/socfpga-dw-mshc.txt
new file mode 100644
index 000000000000..4897bea7e3f8
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/socfpga-dw-mshc.txt
@@ -0,0 +1,23 @@
1* Altera SOCFPGA specific extensions to the Synopsys Designware Mobile
2 Storage Host Controller
3
4The Synopsys designware mobile storage host controller is used to interface
5a SoC with storage medium such as eMMC or SD/MMC cards. This file documents
6differences between the core Synopsys dw mshc controller properties described
7by synopsys-dw-mshc.txt and the properties used by the Altera SOCFPGA specific
8extensions to the Synopsys Designware Mobile Storage Host Controller.
9
10Required Properties:
11
12* compatible: should be
13 - "altr,socfpga-dw-mshc": for Altera's SOCFPGA platform
14
15Example:
16
17 mmc: dwmmc0@ff704000 {
18 compatible = "altr,socfpga-dw-mshc";
19 reg = <0xff704000 0x1000>;
20 interrupts = <0 129 4>;
21 #address-cells = <1>;
22 #size-cells = <0>;
23 };
diff --git a/Documentation/devicetree/bindings/net/socfpga-dwmac.txt b/Documentation/devicetree/bindings/net/socfpga-dwmac.txt
new file mode 100644
index 000000000000..d53d3765b2c6
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/socfpga-dwmac.txt
@@ -0,0 +1,35 @@
1Altera SOCFPGA SoC DWMAC controller
2
3The device node has following properties.
4
5Required properties:
6 - compatible : Should contain "altr,socfpga-stmmac"
7 - altr,sysmgr-syscon : Should be the phandle to the system manager node that
8 encompasses the glue register, and the register offset.
9
10Sub-nodes:
11The dwmac core should be added as subnode to SOCFPGA dwmac glue.
12- dwmac : The binding details of dwmac can be found in
13 Documentation/devicetree/bindings/net/stmmac.txt
14
15Example:
16
17ethernet0: ethernet0 {
18 #address-cells = <1>;
19 #size-cells = <1>;
20
21 compatible = "altr,socfpga-stmmac";
22 altr,sysmgr-syscon = <&sysmgr 0x60>;
23 status = "disabled";
24 ranges;
25
26 gmac0: gmac0@ff700000 {
27 compatible = "snps,dwmac-3.70a", "snps,dwmac";
28 reg = <0xff700000 0x2000>;
29 interrupts = <0 115 4>;
30 interrupt-names = "macirq";
31 mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */
32 clocks = <&emac0_clk>;
33 clock-names = "stmmaceth";
34 };
35};
diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi
index 537f1a5c07f5..404553c97f31 100644
--- a/arch/arm/boot/dts/socfpga.dtsi
+++ b/arch/arm/boot/dts/socfpga.dtsi
@@ -92,7 +92,12 @@
92 #address-cells = <1>; 92 #address-cells = <1>;
93 #size-cells = <0>; 93 #size-cells = <0>;
94 94
95 osc: osc1 { 95 osc1: osc1 {
96 #clock-cells = <0>;
97 compatible = "fixed-clock";
98 };
99
100 osc2: osc2 {
96 #clock-cells = <0>; 101 #clock-cells = <0>;
97 compatible = "fixed-clock"; 102 compatible = "fixed-clock";
98 }; 103 };
@@ -100,7 +105,11 @@
100 f2s_periph_ref_clk: f2s_periph_ref_clk { 105 f2s_periph_ref_clk: f2s_periph_ref_clk {
101 #clock-cells = <0>; 106 #clock-cells = <0>;
102 compatible = "fixed-clock"; 107 compatible = "fixed-clock";
103 clock-frequency = <10000000>; 108 };
109
110 f2s_sdram_ref_clk: f2s_sdram_ref_clk {
111 #clock-cells = <0>;
112 compatible = "fixed-clock";
104 }; 113 };
105 114
106 main_pll: main_pll { 115 main_pll: main_pll {
@@ -108,7 +117,7 @@
108 #size-cells = <0>; 117 #size-cells = <0>;
109 #clock-cells = <0>; 118 #clock-cells = <0>;
110 compatible = "altr,socfpga-pll-clock"; 119 compatible = "altr,socfpga-pll-clock";
111 clocks = <&osc>; 120 clocks = <&osc1>;
112 reg = <0x40>; 121 reg = <0x40>;
113 122
114 mpuclk: mpuclk { 123 mpuclk: mpuclk {
@@ -162,7 +171,7 @@
162 #size-cells = <0>; 171 #size-cells = <0>;
163 #clock-cells = <0>; 172 #clock-cells = <0>;
164 compatible = "altr,socfpga-pll-clock"; 173 compatible = "altr,socfpga-pll-clock";
165 clocks = <&osc>; 174 clocks = <&osc1>, <&osc2>, <&f2s_periph_ref_clk>;
166 reg = <0x80>; 175 reg = <0x80>;
167 176
168 emac0_clk: emac0_clk { 177 emac0_clk: emac0_clk {
@@ -213,7 +222,7 @@
213 #size-cells = <0>; 222 #size-cells = <0>;
214 #clock-cells = <0>; 223 #clock-cells = <0>;
215 compatible = "altr,socfpga-pll-clock"; 224 compatible = "altr,socfpga-pll-clock";
216 clocks = <&osc>; 225 clocks = <&osc1>, <&osc2>, <&f2s_sdram_ref_clk>;
217 reg = <0xC0>; 226 reg = <0xC0>;
218 227
219 ddr_dqs_clk: ddr_dqs_clk { 228 ddr_dqs_clk: ddr_dqs_clk {
@@ -441,26 +450,43 @@
441 }; 450 };
442 }; 451 };
443 452
444 gmac0: ethernet@ff700000 { 453 ethernet0: ethernet0 {
445 compatible = "altr,socfpga-stmmac", "snps,dwmac-3.70a", "snps,dwmac"; 454 #address-cells = <1>;
446 reg = <0xff700000 0x2000>; 455 #size-cells = <1>;
447 interrupts = <0 115 4>; 456 compatible = "altr,socfpga-stmmac";
448 interrupt-names = "macirq"; 457 altr,sysmgr-syscon = <&sysmgr 0x60>;
449 mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */
450 clocks = <&emac0_clk>;
451 clock-names = "stmmaceth";
452 status = "disabled"; 458 status = "disabled";
459 ranges;
460
461 gmac0: gmac0@ff700000 {
462 compatible = "snps,dwmac-3.70a", "snps,dwmac";
463 reg = <0xff700000 0x2000>;
464 interrupts = <0 115 4>;
465 interrupt-names = "macirq";
466 mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */
467 clocks = <&emac0_clk>;
468 clock-names = "stmmaceth";
469 };
453 }; 470 };
454 471
455 gmac1: ethernet@ff702000 { 472 ethernet1: ethernet1 {
456 compatible = "altr,socfpga-stmmac", "snps,dwmac-3.70a", "snps,dwmac"; 473 #address-cells = <1>;
457 reg = <0xff702000 0x2000>; 474 #size-cells = <1>;
458 interrupts = <0 120 4>; 475 compatible = "altr,socfpga-stmmac";
459 interrupt-names = "macirq"; 476 altr,sysmgr-syscon = <&sysmgr 0x60>;
460 mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */
461 clocks = <&emac1_clk>;
462 clock-names = "stmmaceth";
463 status = "disabled"; 477 status = "disabled";
478 ranges;
479
480 gmac1: gmac1@ff702000 {
481 device_type = "network";
482 compatible = "snps,dwmac-3.70a", "snps,dwmac";
483 reg = <0xff702000 0x2000>;
484 interrupts = <0 120 4>;
485 interrupt-names = "macirq";
486 mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */
487 clocks = <&emac1_clk>;
488 clock-names = "stmmaceth";
489 };
464 }; 490 };
465 491
466 L2: l2-cache@fffef000 { 492 L2: l2-cache@fffef000 {
@@ -473,6 +499,17 @@
473 arm,data-latency = <2 1 1>; 499 arm,data-latency = <2 1 1>;
474 }; 500 };
475 501
502 mmc: dwmmc0@ff704000 {
503 compatible = "altr,socfpga-dw-mshc";
504 reg = <0xff704000 0x1000>;
505 interrupts = <0 139 4>;
506 fifo-depth = <0x400>;
507 #address-cells = <1>;
508 #size-cells = <0>;
509 clocks = <&l4_mp_clk>, <&sdmmc_clk>;
510 clock-names = "biu", "ciu";
511 };
512
476 /* Local timer */ 513 /* Local timer */
477 timer@fffec600 { 514 timer@fffec600 {
478 compatible = "arm,cortex-a9-twd-timer"; 515 compatible = "arm,cortex-a9-twd-timer";
@@ -526,9 +563,9 @@
526 reg = <0xffd05000 0x1000>; 563 reg = <0xffd05000 0x1000>;
527 }; 564 };
528 565
529 sysmgr@ffd08000 { 566 sysmgr: sysmgr@ffd08000 {
530 compatible = "altr,sys-mgr"; 567 compatible = "altr,sys-mgr", "syscon";
531 reg = <0xffd08000 0x4000>; 568 reg = <0xffd08000 0x4000>;
532 }; 569 };
533 }; 570 };
534}; 571};
diff --git a/arch/arm/boot/dts/socfpga_arria5.dtsi b/arch/arm/boot/dts/socfpga_arria5.dtsi
index a85b4043f888..6c87b7070ca7 100644
--- a/arch/arm/boot/dts/socfpga_arria5.dtsi
+++ b/arch/arm/boot/dts/socfpga_arria5.dtsi
@@ -27,6 +27,17 @@
27 }; 27 };
28 }; 28 };
29 29
30 dwmmc0@ff704000 {
31 num-slots = <1>;
32 supports-highspeed;
33 broken-cd;
34
35 slot@0 {
36 reg = <0>;
37 bus-width = <4>;
38 };
39 };
40
30 serial0@ffc02000 { 41 serial0@ffc02000 {
31 clock-frequency = <100000000>; 42 clock-frequency = <100000000>;
32 }; 43 };
diff --git a/arch/arm/boot/dts/socfpga_arria5_socdk.dts b/arch/arm/boot/dts/socfpga_arria5_socdk.dts
index 5beffb2265f4..2d6b38ba9370 100644
--- a/arch/arm/boot/dts/socfpga_arria5_socdk.dts
+++ b/arch/arm/boot/dts/socfpga_arria5_socdk.dts
@@ -37,4 +37,28 @@
37 */ 37 */
38 ethernet0 = &gmac1; 38 ethernet0 = &gmac1;
39 }; 39 };
40
41 aliases {
42 /* this allow the ethaddr uboot environmnet variable contents
43 * to be added to the gmac1 device tree blob.
44 */
45 ethernet0 = &gmac1;
46 };
47};
48
49&ethernet1 {
50 status = "okay";
51};
52
53&gmac1 {
54 phy-mode = "rgmii";
55
56 rxd0-skew-ps = <0>;
57 rxd1-skew-ps = <0>;
58 rxd2-skew-ps = <0>;
59 rxd3-skew-ps = <0>;
60 txen-skew-ps = <0>;
61 txc-skew-ps = <2600>;
62 rxdv-skew-ps = <0>;
63 rxc-skew-ps = <2000>;
40}; 64};
diff --git a/arch/arm/boot/dts/socfpga_cyclone5.dtsi b/arch/arm/boot/dts/socfpga_cyclone5.dtsi
index a8716f6dbe2e..ca41b0ebf461 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5.dtsi
+++ b/arch/arm/boot/dts/socfpga_cyclone5.dtsi
@@ -28,6 +28,17 @@
28 }; 28 };
29 }; 29 };
30 30
31 dwmmc0@ff704000 {
32 num-slots = <1>;
33 supports-highspeed;
34 broken-cd;
35
36 slot@0 {
37 reg = <0>;
38 bus-width = <4>;
39 };
40 };
41
31 ethernet@ff702000 { 42 ethernet@ff702000 {
32 phy-mode = "rgmii"; 43 phy-mode = "rgmii";
33 phy-addr = <0xffffffff>; /* probe for phy addr */ 44 phy-addr = <0xffffffff>; /* probe for phy addr */
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts b/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
index 2ee52ab8cabb..26c63a07f8b9 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
+++ b/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
@@ -38,3 +38,20 @@
38 ethernet0 = &gmac1; 38 ethernet0 = &gmac1;
39 }; 39 };
40}; 40};
41
42&ethernet1 {
43 status = "okay";
44};
45
46&gmac1 {
47 phy-mode = "rgmii";
48
49 rxd0-skew-ps = <0>;
50 rxd1-skew-ps = <0>;
51 rxd2-skew-ps = <0>;
52 rxd3-skew-ps = <0>;
53 txen-skew-ps = <0>;
54 txc-skew-ps = <2600>;
55 rxdv-skew-ps = <0>;
56 rxc-skew-ps = <2000>;
57};
diff --git a/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts b/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
index 50b99a2c12ae..469bb5cac886 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
+++ b/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
@@ -30,8 +30,28 @@
30 device_type = "memory"; 30 device_type = "memory";
31 reg = <0x0 0x40000000>; /* 1GB */ 31 reg = <0x0 0x40000000>; /* 1GB */
32 }; 32 };
33
34 aliases {
35 /* this allow the ethaddr uboot environmnet variable contents
36 * to be added to the gmac1 device tree blob.
37 */
38 ethernet0 = &gmac1;
39 };
33}; 40};
34 41
35&gmac1 { 42&ethernet1 {
36 status = "okay"; 43 status = "okay";
37}; 44};
45
46&gmac1 {
47 phy-mode = "rgmii";
48
49 rxd0-skew-ps = <0>;
50 rxd1-skew-ps = <0>;
51 rxd2-skew-ps = <0>;
52 rxd3-skew-ps = <0>;
53 txen-skew-ps = <0>;
54 txc-skew-ps = <2600>;
55 rxdv-skew-ps = <0>;
56 rxc-skew-ps = <2000>;
57};
diff --git a/arch/arm/boot/dts/socfpga_vt.dts b/arch/arm/boot/dts/socfpga_vt.dts
index d1ec0cab2dee..91f6ccf714ee 100644
--- a/arch/arm/boot/dts/socfpga_vt.dts
+++ b/arch/arm/boot/dts/socfpga_vt.dts
@@ -41,6 +41,17 @@
41 }; 41 };
42 }; 42 };
43 43
44 dwmmc0@ff704000 {
45 num-slots = <1>;
46 supports-highspeed;
47 broken-cd;
48
49 slot@0 {
50 reg = <0>;
51 bus-width = <4>;
52 };
53 };
54
44 ethernet@ff700000 { 55 ethernet@ff700000 {
45 phy-mode = "gmii"; 56 phy-mode = "gmii";
46 status = "okay"; 57 status = "okay";
@@ -75,3 +86,11 @@
75 }; 86 };
76 }; 87 };
77}; 88};
89
90&ethernet0 {
91 status = "okay";
92};
93
94&gmac0 {
95 phy-mode = "gmii";
96};
diff --git a/arch/arm/configs/socfpga_defconfig b/arch/arm/configs/socfpga_defconfig
index 4e1ce211d43f..e3a05e8801d8 100644
--- a/arch/arm/configs/socfpga_defconfig
+++ b/arch/arm/configs/socfpga_defconfig
@@ -52,6 +52,7 @@ CONFIG_BLK_DEV_SD=y
52# CONFIG_SCSI_LOWLEVEL is not set 52# CONFIG_SCSI_LOWLEVEL is not set
53CONFIG_NETDEVICES=y 53CONFIG_NETDEVICES=y
54CONFIG_STMMAC_ETH=y 54CONFIG_STMMAC_ETH=y
55CONFIG_MICREL_PHY=y
55# CONFIG_STMMAC_PHY_ID_ZERO_WORKAROUND is not set 56# CONFIG_STMMAC_PHY_ID_ZERO_WORKAROUND is not set
56CONFIG_INPUT_EVDEV=y 57CONFIG_INPUT_EVDEV=y
57# CONFIG_SERIO_SERPORT is not set 58# CONFIG_SERIO_SERPORT is not set
@@ -66,6 +67,9 @@ CONFIG_SERIAL_8250_DW=y
66CONFIG_EXT2_FS=y 67CONFIG_EXT2_FS=y
67CONFIG_EXT2_FS_XATTR=y 68CONFIG_EXT2_FS_XATTR=y
68CONFIG_EXT2_FS_POSIX_ACL=y 69CONFIG_EXT2_FS_POSIX_ACL=y
70CONFIG_EXT3_FS=y
71CONFIG_NFS_FS=y
72CONFIG_ROOT_NFS=y
69# CONFIG_DNOTIFY is not set 73# CONFIG_DNOTIFY is not set
70# CONFIG_INOTIFY_USER is not set 74# CONFIG_INOTIFY_USER is not set
71CONFIG_VFAT_FS=y 75CONFIG_VFAT_FS=y
@@ -82,3 +86,5 @@ CONFIG_DEBUG_INFO=y
82CONFIG_ENABLE_DEFAULT_TRACERS=y 86CONFIG_ENABLE_DEFAULT_TRACERS=y
83CONFIG_DEBUG_USER=y 87CONFIG_DEBUG_USER=y
84CONFIG_XZ_DEC=y 88CONFIG_XZ_DEC=y
89CONFIG_MMC=y
90CONFIG_MMC_DW=y
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index ecadecea79b2..73df8b6c6fb4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -1,4 +1,5 @@
1obj-$(CONFIG_STMMAC_ETH) += stmmac.o 1obj-$(CONFIG_STMMAC_ETH) += stmmac.o
2stmmac-$(CONFIG_ARCH_SOCFPGA) += dwmac-socfpga.o
2stmmac-$(CONFIG_STMMAC_PLATFORM) += stmmac_platform.o 3stmmac-$(CONFIG_STMMAC_PLATFORM) += stmmac_platform.o
3stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o 4stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o
4stmmac-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o 5stmmac-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.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..c7f034b9583c
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -0,0 +1,183 @@
1/* Copyright (C) 2014 Altera Corporation
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 as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Adopted from dwmac-sti.c
17 */
18
19#include <linux/clk.h>
20#include <linux/module.h>
21#include <linux/kernel.h>
22#include <linux/mfd/syscon.h>
23#include <linux/of.h>
24#include <linux/of_address.h>
25#include <linux/of_net.h>
26#include <linux/of_platform.h>
27#include <linux/phy.h>
28#include <linux/platform_device.h>
29#include <linux/regmap.h>
30#include <linux/stmmac.h>
31
32#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII 0x0
33#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII 0x1
34#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII 0x2
35#define SYSMGR_EMACGRP_CTRL_PHYSEL_WIDTH 2
36#define SYSMGR_EMACGRP_CTRL_PHYSEL_MASK 0x00000003
37
38struct socfpga_dwmac {
39 int interface;
40 u32 reg_offset;
41 struct device *dev;
42 struct regmap *sys_mgr_base_addr;
43 struct device_node *dwmac_np;
44};
45
46static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *dev)
47{
48 struct device_node *np = dev->of_node;
49 struct device_node *stmmac_np;
50 struct regmap *sys_mgr_base_addr;
51 u32 reg_offset;
52 int ret;
53
54 stmmac_np = of_get_next_available_child(np, NULL);
55 if (!stmmac_np) {
56 dev_info(dev, "No dwmac node found\n");
57 return -EINVAL;
58 }
59
60 if (!of_device_is_compatible(stmmac_np, "snps,dwmac")) {
61 dev_info(dev, "dwmac node isn't compatible with snps,dwmac\n");
62 return -EINVAL;
63 }
64
65 dwmac->interface = of_get_phy_mode(stmmac_np);
66 of_node_put(stmmac_np);
67
68 sys_mgr_base_addr = syscon_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon");
69 if (IS_ERR(sys_mgr_base_addr)) {
70 dev_info(dev, "No sysmgr-syscon node found\n");
71 return PTR_ERR(sys_mgr_base_addr);
72 }
73
74 ret = of_property_read_u32_index(np, "altr,sysmgr-syscon", 1, &reg_offset);
75 if (ret) {
76 dev_info(dev, "Could not reg_offset into sysmgr-syscon!\n");
77 return -EINVAL;
78 }
79
80 dwmac->reg_offset = reg_offset;
81 dwmac->sys_mgr_base_addr = sys_mgr_base_addr;
82 dwmac->dwmac_np = stmmac_np;
83 dwmac->dev = dev;
84
85 return 0;
86}
87
88static int socfpga_dwmac_setup(struct socfpga_dwmac *dwmac)
89{
90 struct regmap *sys_mgr_base_addr = dwmac->sys_mgr_base_addr;
91 int phymode = dwmac->interface;
92 u32 reg_offset = dwmac->reg_offset;
93 u32 ctrl, val, shift = 0;
94
95 if (of_machine_is_compatible("altr,socfpga-vt"))
96 return 0;
97
98 switch (phymode) {
99 case PHY_INTERFACE_MODE_RGMII:
100 val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII;
101 break;
102 case PHY_INTERFACE_MODE_MII:
103 case PHY_INTERFACE_MODE_GMII:
104 val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
105 break;
106 default:
107 dev_err(dwmac->dev, "bad phy mode %d\n", phymode);
108 return -EINVAL;
109 }
110
111 regmap_read(sys_mgr_base_addr, reg_offset, &ctrl);
112 ctrl &= ~(SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << shift);
113 ctrl |= val << shift;
114
115 regmap_write(sys_mgr_base_addr, reg_offset, ctrl);
116 return 0;
117}
118
119static int socfpga_dwmac_probe(struct platform_device *pdev)
120{
121 struct device *dev = &pdev->dev;
122 struct device_node *node = dev->of_node;
123 int ret = -ENOMEM;
124 struct socfpga_dwmac *dwmac;
125
126 dwmac = devm_kzalloc(dev, sizeof(*dwmac), GFP_KERNEL);
127 if (!dwmac)
128 return -ENOMEM;
129
130 ret = socfpga_dwmac_parse_data(dwmac, dev);
131 if (ret) {
132 dev_err(dev, "Unable to parse OF data\n");
133 return ret;
134 }
135
136 ret = socfpga_dwmac_setup(dwmac);
137 if (ret) {
138 dev_err(dev, "couldn't setup SoC glue (%d)\n", ret);
139 return ret;
140 }
141
142 if (node) {
143 ret = of_platform_populate(node, NULL, NULL, dev);
144 if (ret) {
145 dev_err(dev, "failed to add dwmac core\n");
146 return ret;
147 }
148 } else {
149 dev_err(dev, "no device node, failed to add dwmac core\n");
150 return -ENODEV;
151 }
152
153 platform_set_drvdata(pdev, dwmac);
154
155 return 0;
156}
157
158static int socfpga_dwmac_remove(struct platform_device *pdev)
159{
160 return 0;
161}
162
163static const struct of_device_id socfpga_dwmac_match[] = {
164 { .compatible = "altr,socfpga-stmmac" },
165 {},
166};
167MODULE_DEVICE_TABLE(of, socfpga_dwmac_match);
168
169static struct platform_driver socfpga_dwmac_driver = {
170 .probe = socfpga_dwmac_probe,
171 .remove = socfpga_dwmac_remove,
172 .driver = {
173 .name = "socfpga-dwmac",
174 .of_match_table = of_match_ptr(socfpga_dwmac_match),
175 },
176};
177
178module_platform_driver(socfpga_dwmac_driver);
179
180MODULE_ALIAS("platform:socfpga-dwmac");
181MODULE_AUTHOR("Dinh Nguyen <dinguyen@altera.com>");
182MODULE_LICENSE("GPL v2");
183MODULE_DESCRIPTION("Altera SOCFPGA DWMAC Glue Layer");