1/** 2 * dwmac-rk.c - Rockchip RK3288 DWMAC specific glue layer 3 * 4 * Copyright (C) 2014 Chen-Zhi (Roger Chen) 5 * 6 * Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com> 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 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 */ 18 19#include <linux/stmmac.h> 20#include <linux/bitops.h> 21#include <linux/clk.h> 22#include <linux/phy.h> 23#include <linux/of_net.h> 24#include <linux/gpio.h> 25#include <linux/module.h> 26#include <linux/of_gpio.h> 27#include <linux/of_device.h> 28#include <linux/platform_device.h> 29#include <linux/regulator/consumer.h> 30#include <linux/delay.h> 31#include <linux/mfd/syscon.h> 32#include <linux/regmap.h> 33 34#include "stmmac_platform.h" 35 36struct rk_priv_data; 37struct rk_gmac_ops { 38 void (*set_to_rgmii)(struct rk_priv_data *bsp_priv, 39 int tx_delay, int rx_delay); 40 void (*set_to_rmii)(struct rk_priv_data *bsp_priv); 41 void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed); 42 void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed); 43}; 44 45struct rk_priv_data { 46 struct platform_device *pdev; 47 int phy_iface; 48 struct regulator *regulator; 49 const struct rk_gmac_ops *ops; 50 51 bool clk_enabled; 52 bool clock_input; 53 54 struct clk *clk_mac; 55 struct clk *gmac_clkin; 56 struct clk *mac_clk_rx; 57 struct clk *mac_clk_tx; 58 struct clk *clk_mac_ref; 59 struct clk *clk_mac_refout; 60 struct clk *aclk_mac; 61 struct clk *pclk_mac; 62 63 int tx_delay; 64 int rx_delay; 65 66 struct regmap *grf; 67}; 68 69#define HIWORD_UPDATE(val, mask, shift) \ 70 ((val) << (shift) | (mask) << ((shift) + 16)) 71 72#define GRF_BIT(nr) (BIT(nr) | BIT(nr+16)) 73#define GRF_CLR_BIT(nr) (BIT(nr+16)) 74 75#define RK3288_GRF_SOC_CON1 0x0248 76#define RK3288_GRF_SOC_CON3 0x0250 77 78/*RK3288_GRF_SOC_CON1*/ 79#define RK3288_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(6) | GRF_CLR_BIT(7) | \ 80 GRF_CLR_BIT(8)) 81#define RK3288_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | \ 82 GRF_BIT(8)) 83#define RK3288_GMAC_FLOW_CTRL GRF_BIT(9) 84#define RK3288_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(9) 85#define RK3288_GMAC_SPEED_10M GRF_CLR_BIT(10) 86#define RK3288_GMAC_SPEED_100M GRF_BIT(10) 87#define RK3288_GMAC_RMII_CLK_25M GRF_BIT(11) 88#define RK3288_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(11) 89#define RK3288_GMAC_CLK_125M (GRF_CLR_BIT(12) | GRF_CLR_BIT(13)) 90#define RK3288_GMAC_CLK_25M (GRF_BIT(12) | GRF_BIT(13)) 91#define RK3288_GMAC_CLK_2_5M (GRF_CLR_BIT(12) | GRF_BIT(13)) 92#define RK3288_GMAC_RMII_MODE GRF_BIT(14) 93#define RK3288_GMAC_RMII_MODE_CLR GRF_CLR_BIT(14) 94 95/*RK3288_GRF_SOC_CON3*/ 96#define RK3288_GMAC_TXCLK_DLY_ENABLE GRF_BIT(14) 97#define RK3288_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14) 98#define RK3288_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 99#define RK3288_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 100#define RK3288_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 101#define RK3288_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 102 103static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv, 104 int tx_delay, int rx_delay) 105{ 106 struct device *dev = &bsp_priv->pdev->dev; 107 108 if (IS_ERR(bsp_priv->grf)) { 109 dev_err(dev, "Missing rockchip,grf property\n"); 110 return; 111 } 112 113 regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 114 RK3288_GMAC_PHY_INTF_SEL_RGMII | 115 RK3288_GMAC_RMII_MODE_CLR); 116 regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3, 117 RK3288_GMAC_RXCLK_DLY_ENABLE | 118 RK3288_GMAC_TXCLK_DLY_ENABLE | 119 RK3288_GMAC_CLK_RX_DL_CFG(rx_delay) | 120 RK3288_GMAC_CLK_TX_DL_CFG(tx_delay)); 121} 122 123static void rk3288_set_to_rmii(struct rk_priv_data *bsp_priv) 124{ 125 struct device *dev = &bsp_priv->pdev->dev; 126 127 if (IS_ERR(bsp_priv->grf)) { 128 dev_err(dev, "Missing rockchip,grf property\n"); 129 return; 130 } 131 132 regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 133 RK3288_GMAC_PHY_INTF_SEL_RMII | RK3288_GMAC_RMII_MODE); 134} 135 136static void rk3288_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 137{ 138 struct device *dev = &bsp_priv->pdev->dev; 139 140 if (IS_ERR(bsp_priv->grf)) { 141 dev_err(dev, "Missing rockchip,grf property\n"); 142 return; 143 } 144 145 if (speed == 10) 146 regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 147 RK3288_GMAC_CLK_2_5M); 148 else if (speed == 100) 149 regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 150 RK3288_GMAC_CLK_25M); 151 else if (speed == 1000) 152 regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 153 RK3288_GMAC_CLK_125M); 154 else 155 dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 156} 157 158static void rk3288_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 159{ 160 struct device *dev = &bsp_priv->pdev->dev; 161 162 if (IS_ERR(bsp_priv->grf)) { 163 dev_err(dev, "Missing rockchip,grf property\n"); 164 return; 165 } 166 167 if (speed == 10) { 168 regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 169 RK3288_GMAC_RMII_CLK_2_5M | 170 RK3288_GMAC_SPEED_10M); 171 } else if (speed == 100) { 172 regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 173 RK3288_GMAC_RMII_CLK_25M | 174 RK3288_GMAC_SPEED_100M); 175 } else { 176 dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 177 } 178} 179 180static const struct rk_gmac_ops rk3288_ops = { 181 .set_to_rgmii = rk3288_set_to_rgmii, 182 .set_to_rmii = rk3288_set_to_rmii, 183 .set_rgmii_speed = rk3288_set_rgmii_speed, 184 .set_rmii_speed = rk3288_set_rmii_speed, 185}; 186 187#define RK3368_GRF_SOC_CON15 0x043c 188#define RK3368_GRF_SOC_CON16 0x0440 189 190/* RK3368_GRF_SOC_CON15 */ 191#define RK3368_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 192 GRF_CLR_BIT(11)) 193#define RK3368_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 194 GRF_BIT(11)) 195#define RK3368_GMAC_FLOW_CTRL GRF_BIT(8) 196#define RK3368_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 197#define RK3368_GMAC_SPEED_10M GRF_CLR_BIT(7) 198#define RK3368_GMAC_SPEED_100M GRF_BIT(7) 199#define RK3368_GMAC_RMII_CLK_25M GRF_BIT(3) 200#define RK3368_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 201#define RK3368_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 202#define RK3368_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 203#define RK3368_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 204#define RK3368_GMAC_RMII_MODE GRF_BIT(6) 205#define RK3368_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 206 207/* RK3368_GRF_SOC_CON16 */ 208#define RK3368_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 209#define RK3368_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 210#define RK3368_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 211#define RK3368_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 212#define RK3368_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 213#define RK3368_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 214 215static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv, 216 int tx_delay, int rx_delay) 217{ 218 struct device *dev = &bsp_priv->pdev->dev; 219 220 if (IS_ERR(bsp_priv->grf)) { 221 dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 222 return; 223 } 224 225 regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 226 RK3368_GMAC_PHY_INTF_SEL_RGMII | 227 RK3368_GMAC_RMII_MODE_CLR); 228 regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16, 229 RK3368_GMAC_RXCLK_DLY_ENABLE | 230 RK3368_GMAC_TXCLK_DLY_ENABLE | 231 RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) | 232 RK3368_GMAC_CLK_TX_DL_CFG(tx_delay)); 233} 234 235static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv) 236{ 237 struct device *dev = &bsp_priv->pdev->dev; 238 239 if (IS_ERR(bsp_priv->grf)) { 240 dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 241 return; 242 } 243 244 regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 245 RK3368_GMAC_PHY_INTF_SEL_RMII | RK3368_GMAC_RMII_MODE); 246} 247 248static void rk3368_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 249{ 250 struct device *dev = &bsp_priv->pdev->dev; 251 252 if (IS_ERR(bsp_priv->grf)) { 253 dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 254 return; 255 } 256 257 if (speed == 10) 258 regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 259 RK3368_GMAC_CLK_2_5M); 260 else if (speed == 100) 261 regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 262 RK3368_GMAC_CLK_25M); 263 else if (speed == 1000) 264 regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 265 RK3368_GMAC_CLK_125M); 266 else 267 dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 268} 269 270static void rk3368_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 271{ 272 struct device *dev = &bsp_priv->pdev->dev; 273 274 if (IS_ERR(bsp_priv->grf)) { 275 dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 276 return; 277 } 278 279 if (speed == 10) { 280 regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 281 RK3368_GMAC_RMII_CLK_2_5M | 282 RK3368_GMAC_SPEED_10M); 283 } else if (speed == 100) { 284 regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 285 RK3368_GMAC_RMII_CLK_25M | 286 RK3368_GMAC_SPEED_100M); 287 } else { 288 dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 289 } 290} 291 292static const struct rk_gmac_ops rk3368_ops = { 293 .set_to_rgmii = rk3368_set_to_rgmii, 294 .set_to_rmii = rk3368_set_to_rmii, 295 .set_rgmii_speed = rk3368_set_rgmii_speed, 296 .set_rmii_speed = rk3368_set_rmii_speed, 297}; 298 299static int gmac_clk_init(struct rk_priv_data *bsp_priv) 300{ 301 struct device *dev = &bsp_priv->pdev->dev; 302 303 bsp_priv->clk_enabled = false; 304 305 bsp_priv->mac_clk_rx = devm_clk_get(dev, "mac_clk_rx"); 306 if (IS_ERR(bsp_priv->mac_clk_rx)) 307 dev_err(dev, "cannot get clock %s\n", 308 "mac_clk_rx"); 309 310 bsp_priv->mac_clk_tx = devm_clk_get(dev, "mac_clk_tx"); 311 if (IS_ERR(bsp_priv->mac_clk_tx)) 312 dev_err(dev, "cannot get clock %s\n", 313 "mac_clk_tx"); 314 315 bsp_priv->aclk_mac = devm_clk_get(dev, "aclk_mac"); 316 if (IS_ERR(bsp_priv->aclk_mac)) 317 dev_err(dev, "cannot get clock %s\n", 318 "aclk_mac"); 319 320 bsp_priv->pclk_mac = devm_clk_get(dev, "pclk_mac"); 321 if (IS_ERR(bsp_priv->pclk_mac)) 322 dev_err(dev, "cannot get clock %s\n", 323 "pclk_mac"); 324 325 bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth"); 326 if (IS_ERR(bsp_priv->clk_mac)) 327 dev_err(dev, "cannot get clock %s\n", 328 "stmmaceth"); 329 330 if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) { 331 bsp_priv->clk_mac_ref = devm_clk_get(dev, "clk_mac_ref"); 332 if (IS_ERR(bsp_priv->clk_mac_ref)) 333 dev_err(dev, "cannot get clock %s\n", 334 "clk_mac_ref"); 335 336 if (!bsp_priv->clock_input) { 337 bsp_priv->clk_mac_refout = 338 devm_clk_get(dev, "clk_mac_refout"); 339 if (IS_ERR(bsp_priv->clk_mac_refout)) 340 dev_err(dev, "cannot get clock %s\n", 341 "clk_mac_refout"); 342 } 343 } 344 345 if (bsp_priv->clock_input) { 346 dev_info(dev, "clock input from PHY\n"); 347 } else { 348 if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) 349 clk_set_rate(bsp_priv->clk_mac, 50000000); 350 } 351 352 return 0; 353} 354 355static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable) 356{ 357 int phy_iface = bsp_priv->phy_iface; 358 359 if (enable) { 360 if (!bsp_priv->clk_enabled) { 361 if (phy_iface == PHY_INTERFACE_MODE_RMII) { 362 if (!IS_ERR(bsp_priv->mac_clk_rx)) 363 clk_prepare_enable( 364 bsp_priv->mac_clk_rx); 365 366 if (!IS_ERR(bsp_priv->clk_mac_ref)) 367 clk_prepare_enable( 368 bsp_priv->clk_mac_ref); 369 370 if (!IS_ERR(bsp_priv->clk_mac_refout)) 371 clk_prepare_enable( 372 bsp_priv->clk_mac_refout); 373 } 374 375 if (!IS_ERR(bsp_priv->aclk_mac)) 376 clk_prepare_enable(bsp_priv->aclk_mac); 377 378 if (!IS_ERR(bsp_priv->pclk_mac)) 379 clk_prepare_enable(bsp_priv->pclk_mac); 380 381 if (!IS_ERR(bsp_priv->mac_clk_tx)) 382 clk_prepare_enable(bsp_priv->mac_clk_tx); 383 384 /** 385 * if (!IS_ERR(bsp_priv->clk_mac)) 386 * clk_prepare_enable(bsp_priv->clk_mac); 387 */ 388 mdelay(5); 389 bsp_priv->clk_enabled = true; 390 } 391 } else { 392 if (bsp_priv->clk_enabled) { 393 if (phy_iface == PHY_INTERFACE_MODE_RMII) { 394 if (!IS_ERR(bsp_priv->mac_clk_rx)) 395 clk_disable_unprepare( 396 bsp_priv->mac_clk_rx); 397 398 if (!IS_ERR(bsp_priv->clk_mac_ref)) 399 clk_disable_unprepare( 400 bsp_priv->clk_mac_ref); 401 402 if (!IS_ERR(bsp_priv->clk_mac_refout)) 403 clk_disable_unprepare( 404 bsp_priv->clk_mac_refout); 405 } 406 407 if (!IS_ERR(bsp_priv->aclk_mac)) 408 clk_disable_unprepare(bsp_priv->aclk_mac); 409 410 if (!IS_ERR(bsp_priv->pclk_mac)) 411 clk_disable_unprepare(bsp_priv->pclk_mac); 412 413 if (!IS_ERR(bsp_priv->mac_clk_tx)) 414 clk_disable_unprepare(bsp_priv->mac_clk_tx); 415 /** 416 * if (!IS_ERR(bsp_priv->clk_mac)) 417 * clk_disable_unprepare(bsp_priv->clk_mac); 418 */ 419 bsp_priv->clk_enabled = false; 420 } 421 } 422 423 return 0; 424} 425 426static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable) 427{ 428 struct regulator *ldo = bsp_priv->regulator; 429 int ret; 430 struct device *dev = &bsp_priv->pdev->dev; 431 432 if (!ldo) { 433 dev_err(dev, "no regulator found\n"); 434 return -1; 435 } 436 437 if (enable) { 438 ret = regulator_enable(ldo); 439 if (ret) 440 dev_err(dev, "fail to enable phy-supply\n"); 441 } else { 442 ret = regulator_disable(ldo); 443 if (ret) 444 dev_err(dev, "fail to disable phy-supply\n"); 445 } 446 447 return 0; 448} 449 450static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev, 451 const struct rk_gmac_ops *ops) 452{ 453 struct rk_priv_data *bsp_priv; 454 struct device *dev = &pdev->dev; 455 int ret; 456 const char *strings = NULL; 457 int value; 458 459 bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL); 460 if (!bsp_priv) 461 return ERR_PTR(-ENOMEM); 462 463 bsp_priv->phy_iface = of_get_phy_mode(dev->of_node); 464 bsp_priv->ops = ops; 465 466 bsp_priv->regulator = devm_regulator_get_optional(dev, "phy"); 467 if (IS_ERR(bsp_priv->regulator)) { 468 if (PTR_ERR(bsp_priv->regulator) == -EPROBE_DEFER) { 469 dev_err(dev, "phy regulator is not available yet, deferred probing\n"); 470 return ERR_PTR(-EPROBE_DEFER); 471 } 472 dev_err(dev, "no regulator found\n"); 473 bsp_priv->regulator = NULL; 474 } 475 476 ret = of_property_read_string(dev->of_node, "clock_in_out", &strings); 477 if (ret) { 478 dev_err(dev, "Can not read property: clock_in_out.\n"); 479 bsp_priv->clock_input = true; 480 } else { 481 dev_info(dev, "clock input or output? (%s).\n", 482 strings); 483 if (!strcmp(strings, "input")) 484 bsp_priv->clock_input = true; 485 else 486 bsp_priv->clock_input = false; 487 } 488 489 ret = of_property_read_u32(dev->of_node, "tx_delay", &value); 490 if (ret) { 491 bsp_priv->tx_delay = 0x30; 492 dev_err(dev, "Can not read property: tx_delay."); 493 dev_err(dev, "set tx_delay to 0x%x\n", 494 bsp_priv->tx_delay); 495 } else { 496 dev_info(dev, "TX delay(0x%x).\n", value); 497 bsp_priv->tx_delay = value; 498 } 499 500 ret = of_property_read_u32(dev->of_node, "rx_delay", &value); 501 if (ret) { 502 bsp_priv->rx_delay = 0x10; 503 dev_err(dev, "Can not read property: rx_delay."); 504 dev_err(dev, "set rx_delay to 0x%x\n", 505 bsp_priv->rx_delay); 506 } else { 507 dev_info(dev, "RX delay(0x%x).\n", value); 508 bsp_priv->rx_delay = value; 509 } 510 511 bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node, 512 "rockchip,grf"); 513 bsp_priv->pdev = pdev; 514 515 /*rmii or rgmii*/ 516 if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RGMII) { 517 dev_info(dev, "init for RGMII\n"); 518 bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 519 bsp_priv->rx_delay); 520 } else if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) { 521 dev_info(dev, "init for RMII\n"); 522 bsp_priv->ops->set_to_rmii(bsp_priv); 523 } else { 524 dev_err(dev, "NO interface defined!\n"); 525 } 526 527 gmac_clk_init(bsp_priv); 528 529 return bsp_priv; 530} 531 532static int rk_gmac_init(struct platform_device *pdev, void *priv) 533{ 534 struct rk_priv_data *bsp_priv = priv; 535 int ret; 536 537 ret = phy_power_on(bsp_priv, true); 538 if (ret) 539 return ret; 540 541 ret = gmac_clk_enable(bsp_priv, true); 542 if (ret) 543 return ret; 544 545 return 0; 546} 547 548static void rk_gmac_exit(struct platform_device *pdev, void *priv) 549{ 550 struct rk_priv_data *gmac = priv; 551 552 phy_power_on(gmac, false); 553 gmac_clk_enable(gmac, false); 554} 555 556static void rk_fix_speed(void *priv, unsigned int speed) 557{ 558 struct rk_priv_data *bsp_priv = priv; 559 struct device *dev = &bsp_priv->pdev->dev; 560 561 if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RGMII) 562 bsp_priv->ops->set_rgmii_speed(bsp_priv, speed); 563 else if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) 564 bsp_priv->ops->set_rmii_speed(bsp_priv, speed); 565 else 566 dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface); 567} 568 569static int rk_gmac_probe(struct platform_device *pdev) 570{ 571 struct plat_stmmacenet_data *plat_dat; 572 struct stmmac_resources stmmac_res; 573 const struct rk_gmac_ops *data; 574 int ret; 575 576 data = of_device_get_match_data(&pdev->dev); 577 if (!data) { 578 dev_err(&pdev->dev, "no of match data provided\n"); 579 return -EINVAL; 580 } 581 582 ret = stmmac_get_platform_resources(pdev, &stmmac_res); 583 if (ret) 584 return ret; 585 586 plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac); 587 if (IS_ERR(plat_dat)) 588 return PTR_ERR(plat_dat); 589 590 plat_dat->has_gmac = true; 591 plat_dat->init = rk_gmac_init; 592 plat_dat->exit = rk_gmac_exit; 593 plat_dat->fix_mac_speed = rk_fix_speed; 594 595 plat_dat->bsp_priv = rk_gmac_setup(pdev, data); 596 if (IS_ERR(plat_dat->bsp_priv)) 597 return PTR_ERR(plat_dat->bsp_priv); 598 599 ret = rk_gmac_init(pdev, plat_dat->bsp_priv); 600 if (ret) 601 return ret; 602 603 return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); 604} 605 606static const struct of_device_id rk_gmac_dwmac_match[] = { 607 { .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops }, 608 { .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops }, 609 { } 610}; 611MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match); 612 613static struct platform_driver rk_gmac_dwmac_driver = { 614 .probe = rk_gmac_probe, 615 .remove = stmmac_pltfr_remove, 616 .driver = { 617 .name = "rk_gmac-dwmac", 618 .pm = &stmmac_pltfr_pm_ops, 619 .of_match_table = rk_gmac_dwmac_match, 620 }, 621}; 622module_platform_driver(rk_gmac_dwmac_driver); 623 624MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>"); 625MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer"); 626MODULE_LICENSE("GPL"); 627