1 /* Copyright Altera Corporation (C) 2014. All rights reserved. 2 * 3 * This program is free software; you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License, version 2, 5 * as published by the Free Software Foundation. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * 15 * Adopted from dwmac-sti.c 16 */ 17 18 #include <linux/mfd/syscon.h> 19 #include <linux/of.h> 20 #include <linux/of_address.h> 21 #include <linux/of_net.h> 22 #include <linux/phy.h> 23 #include <linux/regmap.h> 24 #include <linux/reset.h> 25 #include <linux/stmmac.h> 26 #include "stmmac.h" 27 28 #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII 0x0 29 #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII 0x1 30 #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII 0x2 31 #define SYSMGR_EMACGRP_CTRL_PHYSEL_WIDTH 2 32 #define SYSMGR_EMACGRP_CTRL_PHYSEL_MASK 0x00000003 33 34 #define EMAC_SPLITTER_CTRL_REG 0x0 35 #define EMAC_SPLITTER_CTRL_SPEED_MASK 0x3 36 #define EMAC_SPLITTER_CTRL_SPEED_10 0x2 37 #define EMAC_SPLITTER_CTRL_SPEED_100 0x3 38 #define EMAC_SPLITTER_CTRL_SPEED_1000 0x0 39 40 struct socfpga_dwmac { 41 int interface; 42 u32 reg_offset; 43 u32 reg_shift; 44 struct device *dev; 45 struct regmap *sys_mgr_base_addr; 46 struct reset_control *stmmac_rst; 47 void __iomem *splitter_base; 48 }; 49 50 static void socfpga_dwmac_fix_mac_speed(void *priv, unsigned int speed) 51 { 52 struct socfpga_dwmac *dwmac = (struct socfpga_dwmac *)priv; 53 void __iomem *splitter_base = dwmac->splitter_base; 54 u32 val; 55 56 if (!splitter_base) 57 return; 58 59 val = readl(splitter_base + EMAC_SPLITTER_CTRL_REG); 60 val &= ~EMAC_SPLITTER_CTRL_SPEED_MASK; 61 62 switch (speed) { 63 case 1000: 64 val |= EMAC_SPLITTER_CTRL_SPEED_1000; 65 break; 66 case 100: 67 val |= EMAC_SPLITTER_CTRL_SPEED_100; 68 break; 69 case 10: 70 val |= EMAC_SPLITTER_CTRL_SPEED_10; 71 break; 72 default: 73 return; 74 } 75 76 writel(val, splitter_base + EMAC_SPLITTER_CTRL_REG); 77 } 78 79 static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *dev) 80 { 81 struct device_node *np = dev->of_node; 82 struct regmap *sys_mgr_base_addr; 83 u32 reg_offset, reg_shift; 84 int ret; 85 struct device_node *np_splitter; 86 struct resource res_splitter; 87 88 dwmac->stmmac_rst = devm_reset_control_get(dev, 89 STMMAC_RESOURCE_NAME); 90 if (IS_ERR(dwmac->stmmac_rst)) { 91 dev_info(dev, "Could not get reset control!\n"); 92 return -EINVAL; 93 } 94 95 dwmac->interface = of_get_phy_mode(np); 96 97 sys_mgr_base_addr = syscon_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon"); 98 if (IS_ERR(sys_mgr_base_addr)) { 99 dev_info(dev, "No sysmgr-syscon node found\n"); 100 return PTR_ERR(sys_mgr_base_addr); 101 } 102 103 ret = of_property_read_u32_index(np, "altr,sysmgr-syscon", 1, ®_offset); 104 if (ret) { 105 dev_info(dev, "Could not read reg_offset from sysmgr-syscon!\n"); 106 return -EINVAL; 107 } 108 109 ret = of_property_read_u32_index(np, "altr,sysmgr-syscon", 2, ®_shift); 110 if (ret) { 111 dev_info(dev, "Could not read reg_shift from sysmgr-syscon!\n"); 112 return -EINVAL; 113 } 114 115 np_splitter = of_parse_phandle(np, "altr,emac-splitter", 0); 116 if (np_splitter) { 117 if (of_address_to_resource(np_splitter, 0, &res_splitter)) { 118 dev_info(dev, "Missing emac splitter address\n"); 119 return -EINVAL; 120 } 121 122 dwmac->splitter_base = devm_ioremap_resource(dev, &res_splitter); 123 if (IS_ERR(dwmac->splitter_base)) { 124 dev_info(dev, "Failed to mapping emac splitter\n"); 125 return PTR_ERR(dwmac->splitter_base); 126 } 127 } 128 129 dwmac->reg_offset = reg_offset; 130 dwmac->reg_shift = reg_shift; 131 dwmac->sys_mgr_base_addr = sys_mgr_base_addr; 132 dwmac->dev = dev; 133 134 return 0; 135 } 136 137 static int socfpga_dwmac_setup(struct socfpga_dwmac *dwmac) 138 { 139 struct regmap *sys_mgr_base_addr = dwmac->sys_mgr_base_addr; 140 int phymode = dwmac->interface; 141 u32 reg_offset = dwmac->reg_offset; 142 u32 reg_shift = dwmac->reg_shift; 143 u32 ctrl, val; 144 145 switch (phymode) { 146 case PHY_INTERFACE_MODE_RGMII: 147 case PHY_INTERFACE_MODE_RGMII_ID: 148 val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII; 149 break; 150 case PHY_INTERFACE_MODE_MII: 151 case PHY_INTERFACE_MODE_GMII: 152 val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII; 153 break; 154 default: 155 dev_err(dwmac->dev, "bad phy mode %d\n", phymode); 156 return -EINVAL; 157 } 158 159 /* Overwrite val to GMII if splitter core is enabled. The phymode here 160 * is the actual phy mode on phy hardware, but phy interface from 161 * EMAC core is GMII. 162 */ 163 if (dwmac->splitter_base) 164 val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII; 165 166 regmap_read(sys_mgr_base_addr, reg_offset, &ctrl); 167 ctrl &= ~(SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << reg_shift); 168 ctrl |= val << reg_shift; 169 170 regmap_write(sys_mgr_base_addr, reg_offset, ctrl); 171 return 0; 172 } 173 174 static void *socfpga_dwmac_probe(struct platform_device *pdev) 175 { 176 struct device *dev = &pdev->dev; 177 int ret; 178 struct socfpga_dwmac *dwmac; 179 180 dwmac = devm_kzalloc(dev, sizeof(*dwmac), GFP_KERNEL); 181 if (!dwmac) 182 return ERR_PTR(-ENOMEM); 183 184 ret = socfpga_dwmac_parse_data(dwmac, dev); 185 if (ret) { 186 dev_err(dev, "Unable to parse OF data\n"); 187 return ERR_PTR(ret); 188 } 189 190 ret = socfpga_dwmac_setup(dwmac); 191 if (ret) { 192 dev_err(dev, "couldn't setup SoC glue (%d)\n", ret); 193 return ERR_PTR(ret); 194 } 195 196 return dwmac; 197 } 198 199 static void socfpga_dwmac_exit(struct platform_device *pdev, void *priv) 200 { 201 struct socfpga_dwmac *dwmac = priv; 202 203 /* On socfpga platform exit, assert and hold reset to the 204 * enet controller - the default state after a hard reset. 205 */ 206 if (dwmac->stmmac_rst) 207 reset_control_assert(dwmac->stmmac_rst); 208 } 209 210 static int socfpga_dwmac_init(struct platform_device *pdev, void *priv) 211 { 212 struct socfpga_dwmac *dwmac = priv; 213 struct net_device *ndev = platform_get_drvdata(pdev); 214 struct stmmac_priv *stpriv = NULL; 215 int ret = 0; 216 217 if (ndev) 218 stpriv = netdev_priv(ndev); 219 220 /* Assert reset to the enet controller before changing the phy mode */ 221 if (dwmac->stmmac_rst) 222 reset_control_assert(dwmac->stmmac_rst); 223 224 /* Setup the phy mode in the system manager registers according to 225 * devicetree configuration 226 */ 227 ret = socfpga_dwmac_setup(dwmac); 228 229 /* Deassert reset for the phy configuration to be sampled by 230 * the enet controller, and operation to start in requested mode 231 */ 232 if (dwmac->stmmac_rst) 233 reset_control_deassert(dwmac->stmmac_rst); 234 235 /* Before the enet controller is suspended, the phy is suspended. 236 * This causes the phy clock to be gated. The enet controller is 237 * resumed before the phy, so the clock is still gated "off" when 238 * the enet controller is resumed. This code makes sure the phy 239 * is "resumed" before reinitializing the enet controller since 240 * the enet controller depends on an active phy clock to complete 241 * a DMA reset. A DMA reset will "time out" if executed 242 * with no phy clock input on the Synopsys enet controller. 243 * Verified through Synopsys Case #8000711656. 244 * 245 * Note that the phy clock is also gated when the phy is isolated. 246 * Phy "suspend" and "isolate" controls are located in phy basic 247 * control register 0, and can be modified by the phy driver 248 * framework. 249 */ 250 if (stpriv && stpriv->phydev) 251 phy_resume(stpriv->phydev); 252 253 return ret; 254 } 255 256 const struct stmmac_of_data socfpga_gmac_data = { 257 .setup = socfpga_dwmac_probe, 258 .init = socfpga_dwmac_init, 259 .exit = socfpga_dwmac_exit, 260 .fix_mac_speed = socfpga_dwmac_fix_mac_speed, 261 }; 262