Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+413 -26
+23
Documentation/devicetree/bindings/mmc/socfpga-dw-mshc.txt
··· 1 + * Altera SOCFPGA specific extensions to the Synopsys Designware Mobile 2 + Storage Host Controller 3 + 4 + The Synopsys designware mobile storage host controller is used to interface 5 + a SoC with storage medium such as eMMC or SD/MMC cards. This file documents 6 + differences between the core Synopsys dw mshc controller properties described 7 + by synopsys-dw-mshc.txt and the properties used by the Altera SOCFPGA specific 8 + extensions to the Synopsys Designware Mobile Storage Host Controller. 9 + 10 + Required Properties: 11 + 12 + * compatible: should be 13 + - "altr,socfpga-dw-mshc": for Altera's SOCFPGA platform 14 + 15 + Example: 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 + };
+35
Documentation/devicetree/bindings/net/socfpga-dwmac.txt
··· 1 + Altera SOCFPGA SoC DWMAC controller 2 + 3 + The device node has following properties. 4 + 5 + Required 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 + 10 + Sub-nodes: 11 + The 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 + 15 + Example: 16 + 17 + ethernet0: 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 + };
+62 -25
arch/arm/boot/dts/socfpga.dtsi
··· 92 92 #address-cells = <1>; 93 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 101 #clock-cells = <0>; 97 102 compatible = "fixed-clock"; 98 103 }; ··· 105 100 f2s_periph_ref_clk: f2s_periph_ref_clk { 106 101 #clock-cells = <0>; 107 102 compatible = "fixed-clock"; 108 - clock-frequency = <10000000>; 103 + }; 104 + 105 + f2s_sdram_ref_clk: f2s_sdram_ref_clk { 106 + #clock-cells = <0>; 107 + compatible = "fixed-clock"; 109 108 }; 110 109 111 110 main_pll: main_pll { ··· 117 108 #size-cells = <0>; 118 109 #clock-cells = <0>; 119 110 compatible = "altr,socfpga-pll-clock"; 120 - clocks = <&osc>; 111 + clocks = <&osc1>; 121 112 reg = <0x40>; 122 113 123 114 mpuclk: mpuclk { ··· 171 162 #size-cells = <0>; 172 163 #clock-cells = <0>; 173 164 compatible = "altr,socfpga-pll-clock"; 174 - clocks = <&osc>; 165 + clocks = <&osc1>, <&osc2>, <&f2s_periph_ref_clk>; 175 166 reg = <0x80>; 176 167 177 168 emac0_clk: emac0_clk { ··· 222 213 #size-cells = <0>; 223 214 #clock-cells = <0>; 224 215 compatible = "altr,socfpga-pll-clock"; 225 - clocks = <&osc>; 216 + clocks = <&osc1>, <&osc2>, <&f2s_sdram_ref_clk>; 226 217 reg = <0xC0>; 227 218 228 219 ddr_dqs_clk: ddr_dqs_clk { ··· 450 441 }; 451 442 }; 452 443 453 - gmac0: ethernet@ff700000 { 454 - compatible = "altr,socfpga-stmmac", "snps,dwmac-3.70a", "snps,dwmac"; 455 - reg = <0xff700000 0x2000>; 456 - interrupts = <0 115 4>; 457 - interrupt-names = "macirq"; 458 - mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */ 459 - clocks = <&emac0_clk>; 460 - clock-names = "stmmaceth"; 444 + ethernet0: ethernet0 { 445 + #address-cells = <1>; 446 + #size-cells = <1>; 447 + compatible = "altr,socfpga-stmmac"; 448 + altr,sysmgr-syscon = <&sysmgr 0x60>; 461 449 status = "disabled"; 450 + ranges; 451 + 452 + gmac0: gmac0@ff700000 { 453 + compatible = "snps,dwmac-3.70a", "snps,dwmac"; 454 + reg = <0xff700000 0x2000>; 455 + interrupts = <0 115 4>; 456 + interrupt-names = "macirq"; 457 + mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */ 458 + clocks = <&emac0_clk>; 459 + clock-names = "stmmaceth"; 460 + }; 462 461 }; 463 462 464 - gmac1: ethernet@ff702000 { 465 - compatible = "altr,socfpga-stmmac", "snps,dwmac-3.70a", "snps,dwmac"; 466 - reg = <0xff702000 0x2000>; 467 - interrupts = <0 120 4>; 468 - interrupt-names = "macirq"; 469 - mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */ 470 - clocks = <&emac1_clk>; 471 - clock-names = "stmmaceth"; 463 + ethernet1: ethernet1 { 464 + #address-cells = <1>; 465 + #size-cells = <1>; 466 + compatible = "altr,socfpga-stmmac"; 467 + altr,sysmgr-syscon = <&sysmgr 0x60>; 472 468 status = "disabled"; 469 + ranges; 470 + 471 + gmac1: gmac1@ff702000 { 472 + device_type = "network"; 473 + compatible = "snps,dwmac-3.70a", "snps,dwmac"; 474 + reg = <0xff702000 0x2000>; 475 + interrupts = <0 120 4>; 476 + interrupt-names = "macirq"; 477 + mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */ 478 + clocks = <&emac1_clk>; 479 + clock-names = "stmmaceth"; 480 + }; 473 481 }; 474 482 475 483 L2: l2-cache@fffef000 { ··· 497 471 cache-level = <2>; 498 472 arm,tag-latency = <1 1 1>; 499 473 arm,data-latency = <2 1 1>; 474 + }; 475 + 476 + mmc: dwmmc0@ff704000 { 477 + compatible = "altr,socfpga-dw-mshc"; 478 + reg = <0xff704000 0x1000>; 479 + interrupts = <0 139 4>; 480 + fifo-depth = <0x400>; 481 + #address-cells = <1>; 482 + #size-cells = <0>; 483 + clocks = <&l4_mp_clk>, <&sdmmc_clk>; 484 + clock-names = "biu", "ciu"; 500 485 }; 501 486 502 487 /* Local timer */ ··· 563 526 reg = <0xffd05000 0x1000>; 564 527 }; 565 528 566 - sysmgr@ffd08000 { 567 - compatible = "altr,sys-mgr"; 568 - reg = <0xffd08000 0x4000>; 569 - }; 529 + sysmgr: sysmgr@ffd08000 { 530 + compatible = "altr,sys-mgr", "syscon"; 531 + reg = <0xffd08000 0x4000>; 532 + }; 570 533 }; 571 534 };
+11
arch/arm/boot/dts/socfpga_arria5.dtsi
··· 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 41 serial0@ffc02000 { 31 42 clock-frequency = <100000000>; 32 43 };
+24
arch/arm/boot/dts/socfpga_arria5_socdk.dts
··· 37 37 */ 38 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 };
+11
arch/arm/boot/dts/socfpga_cyclone5.dtsi
··· 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 42 ethernet@ff702000 { 32 43 phy-mode = "rgmii"; 33 44 phy-addr = <0xffffffff>; /* probe for phy addr */
+17
arch/arm/boot/dts/socfpga_cyclone5_socdk.dts
··· 38 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 + };
+21 -1
arch/arm/boot/dts/socfpga_cyclone5_sockit.dts
··· 30 30 device_type = "memory"; 31 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 + }; 40 + }; 41 + 42 + &ethernet1 { 43 + status = "okay"; 33 44 }; 34 45 35 46 &gmac1 { 36 - status = "okay"; 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>; 37 57 };
+19
arch/arm/boot/dts/socfpga_vt.dts
··· 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 55 ethernet@ff700000 { 45 56 phy-mode = "gmii"; 46 57 status = "okay"; ··· 85 74 cpu1-start-addr = <0xffd08010>; 86 75 }; 87 76 }; 77 + }; 78 + 79 + &ethernet0 { 80 + status = "okay"; 81 + }; 82 + 83 + &gmac0 { 84 + phy-mode = "gmii"; 88 85 };
+6
arch/arm/configs/socfpga_defconfig
··· 52 52 # CONFIG_SCSI_LOWLEVEL is not set 53 53 CONFIG_NETDEVICES=y 54 54 CONFIG_STMMAC_ETH=y 55 + CONFIG_MICREL_PHY=y 55 56 # CONFIG_STMMAC_PHY_ID_ZERO_WORKAROUND is not set 56 57 CONFIG_INPUT_EVDEV=y 57 58 # CONFIG_SERIO_SERPORT is not set ··· 67 66 CONFIG_EXT2_FS=y 68 67 CONFIG_EXT2_FS_XATTR=y 69 68 CONFIG_EXT2_FS_POSIX_ACL=y 69 + CONFIG_EXT3_FS=y 70 + CONFIG_NFS_FS=y 71 + CONFIG_ROOT_NFS=y 70 72 # CONFIG_DNOTIFY is not set 71 73 # CONFIG_INOTIFY_USER is not set 72 74 CONFIG_VFAT_FS=y ··· 86 82 CONFIG_ENABLE_DEFAULT_TRACERS=y 87 83 CONFIG_DEBUG_USER=y 88 84 CONFIG_XZ_DEC=y 85 + CONFIG_MMC=y 86 + CONFIG_MMC_DW=y
+1
drivers/net/ethernet/stmicro/stmmac/Makefile
··· 1 1 obj-$(CONFIG_STMMAC_ETH) += stmmac.o 2 + stmmac-$(CONFIG_ARCH_SOCFPGA) += dwmac-socfpga.o 2 3 stmmac-$(CONFIG_STMMAC_PLATFORM) += stmmac_platform.o 3 4 stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o 4 5 stmmac-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o
+183
drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
··· 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 + 38 + struct 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 + 46 + static 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 + 88 + static 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 + 119 + static 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 + 158 + static int socfpga_dwmac_remove(struct platform_device *pdev) 159 + { 160 + return 0; 161 + } 162 + 163 + static const struct of_device_id socfpga_dwmac_match[] = { 164 + { .compatible = "altr,socfpga-stmmac" }, 165 + {}, 166 + }; 167 + MODULE_DEVICE_TABLE(of, socfpga_dwmac_match); 168 + 169 + static 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 + 178 + module_platform_driver(socfpga_dwmac_driver); 179 + 180 + MODULE_ALIAS("platform:socfpga-dwmac"); 181 + MODULE_AUTHOR("Dinh Nguyen <dinguyen@altera.com>"); 182 + MODULE_LICENSE("GPL v2"); 183 + MODULE_DESCRIPTION("Altera SOCFPGA DWMAC Glue Layer");