1 /** 2 * dwmac-sti.c - STMicroelectronics DWMAC Specific Glue layer 3 * 4 * Copyright (C) 2003-2014 STMicroelectronics (R&D) Limited 5 * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com> 6 * 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 */ 13 14 #include <linux/kernel.h> 15 #include <linux/slab.h> 16 #include <linux/platform_device.h> 17 #include <linux/stmmac.h> 18 #include <linux/phy.h> 19 #include <linux/mfd/syscon.h> 20 #include <linux/regmap.h> 21 #include <linux/clk.h> 22 #include <linux/of.h> 23 #include <linux/of_net.h> 24 25 /** 26 * STi GMAC glue logic. 27 * -------------------- 28 * 29 * _ 30 * | \ 31 * --------|0 \ ETH_SEL_INTERNAL_NOTEXT_PHYCLK 32 * phyclk | |___________________________________________ 33 * | | | (phyclk-in) 34 * --------|1 / | 35 * int-clk |_ / | 36 * | _ 37 * | | \ 38 * |_______|1 \ ETH_SEL_TX_RETIME_CLK 39 * | |___________________________ 40 * | | (tx-retime-clk) 41 * _______|0 / 42 * | |_ / 43 * _ | 44 * | \ | 45 * --------|0 \ | 46 * clk_125 | |__| 47 * | | ETH_SEL_TXCLK_NOT_CLK125 48 * --------|1 / 49 * txclk |_ / 50 * 51 * 52 * ETH_SEL_INTERNAL_NOTEXT_PHYCLK is valid only for RMII where PHY can 53 * generate 50MHz clock or MAC can generate it. 54 * This bit is configured by "st,ext-phyclk" property. 55 * 56 * ETH_SEL_TXCLK_NOT_CLK125 is only valid for gigabit modes, where the 125Mhz 57 * clock either comes from clk-125 pin or txclk pin. This configuration is 58 * totally driven by the board wiring. This bit is configured by 59 * "st,tx-retime-src" property. 60 * 61 * TXCLK configuration is different for different phy interface modes 62 * and changes according to link speed in modes like RGMII. 63 * 64 * Below table summarizes the clock requirement and clock sources for 65 * supported phy interface modes with link speeds. 66 * ________________________________________________ 67 *| PHY_MODE | 1000 Mbit Link | 100 Mbit Link | 68 * ------------------------------------------------ 69 *| MII | n/a | 25Mhz | 70 *| | | txclk | 71 * ------------------------------------------------ 72 *| GMII | 125Mhz | 25Mhz | 73 *| | clk-125/txclk | txclk | 74 * ------------------------------------------------ 75 *| RGMII | 125Mhz | 25Mhz | 76 *| | clk-125/txclk | clkgen | 77 * ------------------------------------------------ 78 *| RMII | n/a | 25Mhz | 79 *| | |clkgen/phyclk-in | 80 * ------------------------------------------------ 81 * 82 * TX lines are always retimed with a clk, which can vary depending 83 * on the board configuration. Below is the table of these bits 84 * in eth configuration register depending on source of retime clk. 85 * 86 *--------------------------------------------------------------- 87 * src | tx_rt_clk | int_not_ext_phyclk | txclk_n_clk125| 88 *--------------------------------------------------------------- 89 * txclk | 0 | n/a | 1 | 90 *--------------------------------------------------------------- 91 * ck_125| 0 | n/a | 0 | 92 *--------------------------------------------------------------- 93 * phyclk| 1 | 0 | n/a | 94 *--------------------------------------------------------------- 95 * clkgen| 1 | 1 | n/a | 96 *--------------------------------------------------------------- 97 */ 98 99 /* Register definition */ 100 101 /* 3 bits [8:6] 102 * [6:6] ETH_SEL_TXCLK_NOT_CLK125 103 * [7:7] ETH_SEL_INTERNAL_NOTEXT_PHYCLK 104 * [8:8] ETH_SEL_TX_RETIME_CLK 105 * 106 */ 107 108 #define TX_RETIME_SRC_MASK GENMASK(8, 6) 109 #define ETH_SEL_TX_RETIME_CLK BIT(8) 110 #define ETH_SEL_INTERNAL_NOTEXT_PHYCLK BIT(7) 111 #define ETH_SEL_TXCLK_NOT_CLK125 BIT(6) 112 113 #define ENMII_MASK GENMASK(5, 5) 114 #define ENMII BIT(5) 115 116 /** 117 * 3 bits [4:2] 118 * 000-GMII/MII 119 * 001-RGMII 120 * 010-SGMII 121 * 100-RMII 122 */ 123 #define MII_PHY_SEL_MASK GENMASK(4, 2) 124 #define ETH_PHY_SEL_RMII BIT(4) 125 #define ETH_PHY_SEL_SGMII BIT(3) 126 #define ETH_PHY_SEL_RGMII BIT(2) 127 #define ETH_PHY_SEL_GMII 0x0 128 #define ETH_PHY_SEL_MII 0x0 129 130 #define IS_PHY_IF_MODE_RGMII(iface) (iface == PHY_INTERFACE_MODE_RGMII || \ 131 iface == PHY_INTERFACE_MODE_RGMII_ID || \ 132 iface == PHY_INTERFACE_MODE_RGMII_RXID || \ 133 iface == PHY_INTERFACE_MODE_RGMII_TXID) 134 135 #define IS_PHY_IF_MODE_GBIT(iface) (IS_PHY_IF_MODE_RGMII(iface) || \ 136 iface == PHY_INTERFACE_MODE_GMII) 137 138 struct sti_dwmac { 139 int interface; 140 bool ext_phyclk; 141 bool is_tx_retime_src_clk_125; 142 struct clk *clk; 143 int reg; 144 struct device *dev; 145 struct regmap *regmap; 146 }; 147 148 static u32 phy_intf_sels[] = { 149 [PHY_INTERFACE_MODE_MII] = ETH_PHY_SEL_MII, 150 [PHY_INTERFACE_MODE_GMII] = ETH_PHY_SEL_GMII, 151 [PHY_INTERFACE_MODE_RGMII] = ETH_PHY_SEL_RGMII, 152 [PHY_INTERFACE_MODE_RGMII_ID] = ETH_PHY_SEL_RGMII, 153 [PHY_INTERFACE_MODE_SGMII] = ETH_PHY_SEL_SGMII, 154 [PHY_INTERFACE_MODE_RMII] = ETH_PHY_SEL_RMII, 155 }; 156 157 enum { 158 TX_RETIME_SRC_NA = 0, 159 TX_RETIME_SRC_TXCLK = 1, 160 TX_RETIME_SRC_CLK_125, 161 TX_RETIME_SRC_PHYCLK, 162 TX_RETIME_SRC_CLKGEN, 163 }; 164 165 static const char *const tx_retime_srcs[] = { 166 [TX_RETIME_SRC_NA] = "", 167 [TX_RETIME_SRC_TXCLK] = "txclk", 168 [TX_RETIME_SRC_CLK_125] = "clk_125", 169 [TX_RETIME_SRC_PHYCLK] = "phyclk", 170 [TX_RETIME_SRC_CLKGEN] = "clkgen", 171 }; 172 173 static u32 tx_retime_val[] = { 174 [TX_RETIME_SRC_TXCLK] = ETH_SEL_TXCLK_NOT_CLK125, 175 [TX_RETIME_SRC_CLK_125] = 0x0, 176 [TX_RETIME_SRC_PHYCLK] = ETH_SEL_TX_RETIME_CLK, 177 [TX_RETIME_SRC_CLKGEN] = ETH_SEL_TX_RETIME_CLK | 178 ETH_SEL_INTERNAL_NOTEXT_PHYCLK, 179 }; 180 181 static void setup_retime_src(struct sti_dwmac *dwmac, u32 spd) 182 { 183 u32 src = 0, freq = 0; 184 185 if (spd == SPEED_100) { 186 if (dwmac->interface == PHY_INTERFACE_MODE_MII || 187 dwmac->interface == PHY_INTERFACE_MODE_GMII) { 188 src = TX_RETIME_SRC_TXCLK; 189 } else if (dwmac->interface == PHY_INTERFACE_MODE_RMII) { 190 if (dwmac->ext_phyclk) { 191 src = TX_RETIME_SRC_PHYCLK; 192 } else { 193 src = TX_RETIME_SRC_CLKGEN; 194 freq = 50000000; 195 } 196 197 } else if (IS_PHY_IF_MODE_RGMII(dwmac->interface)) { 198 src = TX_RETIME_SRC_CLKGEN; 199 freq = 25000000; 200 } 201 202 if (src == TX_RETIME_SRC_CLKGEN && dwmac->clk) 203 clk_set_rate(dwmac->clk, freq); 204 205 } else if (spd == SPEED_1000) { 206 if (dwmac->is_tx_retime_src_clk_125) 207 src = TX_RETIME_SRC_CLK_125; 208 else 209 src = TX_RETIME_SRC_TXCLK; 210 } 211 212 regmap_update_bits(dwmac->regmap, dwmac->reg, 213 TX_RETIME_SRC_MASK, tx_retime_val[src]); 214 } 215 216 static void sti_dwmac_exit(struct platform_device *pdev, void *priv) 217 { 218 struct sti_dwmac *dwmac = priv; 219 220 if (dwmac->clk) 221 clk_disable_unprepare(dwmac->clk); 222 } 223 224 static void sti_fix_mac_speed(void *priv, unsigned int spd) 225 { 226 struct sti_dwmac *dwmac = priv; 227 228 setup_retime_src(dwmac, spd); 229 230 return; 231 } 232 233 static int sti_dwmac_parse_data(struct sti_dwmac *dwmac, 234 struct platform_device *pdev) 235 { 236 struct resource *res; 237 struct device *dev = &pdev->dev; 238 struct device_node *np = dev->of_node; 239 struct regmap *regmap; 240 int err; 241 242 if (!np) 243 return -EINVAL; 244 245 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sti-ethconf"); 246 if (!res) 247 return -ENODATA; 248 249 regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon"); 250 if (IS_ERR(regmap)) 251 return PTR_ERR(regmap); 252 253 dwmac->dev = dev; 254 dwmac->interface = of_get_phy_mode(np); 255 dwmac->regmap = regmap; 256 dwmac->reg = res->start; 257 dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk"); 258 dwmac->is_tx_retime_src_clk_125 = false; 259 260 if (IS_PHY_IF_MODE_GBIT(dwmac->interface)) { 261 const char *rs; 262 263 err = of_property_read_string(np, "st,tx-retime-src", &rs); 264 if (err < 0) { 265 dev_err(dev, "st,tx-retime-src not specified\n"); 266 return err; 267 } 268 269 if (!strcasecmp(rs, "clk_125")) 270 dwmac->is_tx_retime_src_clk_125 = true; 271 } 272 273 dwmac->clk = devm_clk_get(dev, "sti-ethclk"); 274 275 if (IS_ERR(dwmac->clk)) 276 dwmac->clk = NULL; 277 278 return 0; 279 } 280 281 static int sti_dwmac_init(struct platform_device *pdev, void *priv) 282 { 283 struct sti_dwmac *dwmac = priv; 284 struct regmap *regmap = dwmac->regmap; 285 int iface = dwmac->interface; 286 u32 reg = dwmac->reg; 287 u32 val, spd; 288 289 if (dwmac->clk) 290 clk_prepare_enable(dwmac->clk); 291 292 regmap_update_bits(regmap, reg, MII_PHY_SEL_MASK, phy_intf_sels[iface]); 293 294 val = (iface == PHY_INTERFACE_MODE_REVMII) ? 0 : ENMII; 295 regmap_update_bits(regmap, reg, ENMII_MASK, val); 296 297 if (IS_PHY_IF_MODE_GBIT(iface)) 298 spd = SPEED_1000; 299 else 300 spd = SPEED_100; 301 302 setup_retime_src(dwmac, spd); 303 304 return 0; 305 } 306 307 static void *sti_dwmac_setup(struct platform_device *pdev) 308 { 309 struct sti_dwmac *dwmac; 310 int ret; 311 312 dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL); 313 if (!dwmac) 314 return ERR_PTR(-ENOMEM); 315 316 ret = sti_dwmac_parse_data(dwmac, pdev); 317 if (ret) { 318 dev_err(&pdev->dev, "Unable to parse OF data\n"); 319 return ERR_PTR(ret); 320 } 321 322 return dwmac; 323 } 324 325 const struct stmmac_of_data sti_gmac_data = { 326 .fix_mac_speed = sti_fix_mac_speed, 327 .setup = sti_dwmac_setup, 328 .init = sti_dwmac_init, 329 .exit = sti_dwmac_exit, 330 }; 331