17ad269eaSRoger Chen /** 27ad269eaSRoger Chen * dwmac-rk.c - Rockchip RK3288 DWMAC specific glue layer 37ad269eaSRoger Chen * 47ad269eaSRoger Chen * Copyright (C) 2014 Chen-Zhi (Roger Chen) 57ad269eaSRoger Chen * 67ad269eaSRoger Chen * Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com> 77ad269eaSRoger Chen * 87ad269eaSRoger Chen * This program is free software; you can redistribute it and/or modify 97ad269eaSRoger Chen * it under the terms of the GNU General Public License as published by 107ad269eaSRoger Chen * the Free Software Foundation; either version 2 of the License, or 117ad269eaSRoger Chen * (at your option) any later version. 127ad269eaSRoger Chen * 137ad269eaSRoger Chen * This program is distributed in the hope that it will be useful, 147ad269eaSRoger Chen * but WITHOUT ANY WARRANTY; without even the implied warranty of 157ad269eaSRoger Chen * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 167ad269eaSRoger Chen * GNU General Public License for more details. 177ad269eaSRoger Chen */ 187ad269eaSRoger Chen 197ad269eaSRoger Chen #include <linux/stmmac.h> 207ad269eaSRoger Chen #include <linux/bitops.h> 217ad269eaSRoger Chen #include <linux/clk.h> 227ad269eaSRoger Chen #include <linux/phy.h> 237ad269eaSRoger Chen #include <linux/of_net.h> 247ad269eaSRoger Chen #include <linux/gpio.h> 25e0fb4013SJoachim Eastwood #include <linux/module.h> 267ad269eaSRoger Chen #include <linux/of_gpio.h> 277ad269eaSRoger Chen #include <linux/of_device.h> 28e0fb4013SJoachim Eastwood #include <linux/platform_device.h> 297ad269eaSRoger Chen #include <linux/regulator/consumer.h> 307ad269eaSRoger Chen #include <linux/delay.h> 317ad269eaSRoger Chen #include <linux/mfd/syscon.h> 327ad269eaSRoger Chen #include <linux/regmap.h> 337ad269eaSRoger Chen 34e0fb4013SJoachim Eastwood #include "stmmac_platform.h" 35e0fb4013SJoachim Eastwood 360fb98db1SHeiko Stübner struct rk_priv_data; 370fb98db1SHeiko Stübner struct rk_gmac_ops { 380fb98db1SHeiko Stübner void (*set_to_rgmii)(struct rk_priv_data *bsp_priv, 390fb98db1SHeiko Stübner int tx_delay, int rx_delay); 400fb98db1SHeiko Stübner void (*set_to_rmii)(struct rk_priv_data *bsp_priv); 410fb98db1SHeiko Stübner void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed); 420fb98db1SHeiko Stübner void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed); 430fb98db1SHeiko Stübner }; 440fb98db1SHeiko Stübner 457ad269eaSRoger Chen struct rk_priv_data { 467ad269eaSRoger Chen struct platform_device *pdev; 477ad269eaSRoger Chen int phy_iface; 482e12f536SRomain Perier struct regulator *regulator; 49229666c1SVincent Palatin bool suspended; 5092c2588fSJoachim Eastwood const struct rk_gmac_ops *ops; 517ad269eaSRoger Chen 527ad269eaSRoger Chen bool clk_enabled; 537ad269eaSRoger Chen bool clock_input; 547ad269eaSRoger Chen 557ad269eaSRoger Chen struct clk *clk_mac; 567ad269eaSRoger Chen struct clk *gmac_clkin; 577ad269eaSRoger Chen struct clk *mac_clk_rx; 587ad269eaSRoger Chen struct clk *mac_clk_tx; 597ad269eaSRoger Chen struct clk *clk_mac_ref; 607ad269eaSRoger Chen struct clk *clk_mac_refout; 617ad269eaSRoger Chen struct clk *aclk_mac; 627ad269eaSRoger Chen struct clk *pclk_mac; 637ad269eaSRoger Chen 647ad269eaSRoger Chen int tx_delay; 657ad269eaSRoger Chen int rx_delay; 667ad269eaSRoger Chen 677ad269eaSRoger Chen struct regmap *grf; 687ad269eaSRoger Chen }; 697ad269eaSRoger Chen 707ad269eaSRoger Chen #define HIWORD_UPDATE(val, mask, shift) \ 717ad269eaSRoger Chen ((val) << (shift) | (mask) << ((shift) + 16)) 727ad269eaSRoger Chen 737ad269eaSRoger Chen #define GRF_BIT(nr) (BIT(nr) | BIT(nr+16)) 747ad269eaSRoger Chen #define GRF_CLR_BIT(nr) (BIT(nr+16)) 757ad269eaSRoger Chen 76e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON0 0x0900 77e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON1 0x0904 78e7ffd812SXing Zheng 79e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON0 */ 80e7ffd812SXing Zheng #define RK3228_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 81e7ffd812SXing Zheng #define RK3228_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 82e7ffd812SXing Zheng 83e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON1 */ 84e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RGMII \ 85e7ffd812SXing Zheng (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6)) 86e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RMII \ 87e7ffd812SXing Zheng (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6)) 88e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL GRF_BIT(3) 89e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 90e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_10M GRF_CLR_BIT(2) 91e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_100M GRF_BIT(2) 92e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_25M GRF_BIT(7) 93e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7) 94e7ffd812SXing Zheng #define RK3228_GMAC_CLK_125M (GRF_CLR_BIT(8) | GRF_CLR_BIT(9)) 95e7ffd812SXing Zheng #define RK3228_GMAC_CLK_25M (GRF_BIT(8) | GRF_BIT(9)) 96e7ffd812SXing Zheng #define RK3228_GMAC_CLK_2_5M (GRF_CLR_BIT(8) | GRF_BIT(9)) 97e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE GRF_BIT(10) 98e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE_CLR GRF_CLR_BIT(10) 99e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0) 100e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0) 101e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1) 102e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(1) 103e7ffd812SXing Zheng 104e7ffd812SXing Zheng static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv, 105e7ffd812SXing Zheng int tx_delay, int rx_delay) 106e7ffd812SXing Zheng { 107e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 108e7ffd812SXing Zheng 109e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 110e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 111e7ffd812SXing Zheng return; 112e7ffd812SXing Zheng } 113e7ffd812SXing Zheng 114e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 115e7ffd812SXing Zheng RK3228_GMAC_PHY_INTF_SEL_RGMII | 116e7ffd812SXing Zheng RK3228_GMAC_RMII_MODE_CLR | 117e7ffd812SXing Zheng RK3228_GMAC_RXCLK_DLY_ENABLE | 118e7ffd812SXing Zheng RK3228_GMAC_TXCLK_DLY_ENABLE); 119e7ffd812SXing Zheng 120e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON0, 121e7ffd812SXing Zheng RK3228_GMAC_CLK_RX_DL_CFG(rx_delay) | 122e7ffd812SXing Zheng RK3228_GMAC_CLK_TX_DL_CFG(tx_delay)); 123e7ffd812SXing Zheng } 124e7ffd812SXing Zheng 125e7ffd812SXing Zheng static void rk3228_set_to_rmii(struct rk_priv_data *bsp_priv) 126e7ffd812SXing Zheng { 127e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 128e7ffd812SXing Zheng 129e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 130e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 131e7ffd812SXing Zheng return; 132e7ffd812SXing Zheng } 133e7ffd812SXing Zheng 134e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 135e7ffd812SXing Zheng RK3228_GMAC_PHY_INTF_SEL_RMII | 136e7ffd812SXing Zheng RK3228_GMAC_RMII_MODE); 137e7ffd812SXing Zheng 138e7ffd812SXing Zheng /* set MAC to RMII mode */ 139e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, GRF_BIT(11)); 140e7ffd812SXing Zheng } 141e7ffd812SXing Zheng 142e7ffd812SXing Zheng static void rk3228_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 143e7ffd812SXing Zheng { 144e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 145e7ffd812SXing Zheng 146e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 147e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 148e7ffd812SXing Zheng return; 149e7ffd812SXing Zheng } 150e7ffd812SXing Zheng 151e7ffd812SXing Zheng if (speed == 10) 152e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 153e7ffd812SXing Zheng RK3228_GMAC_CLK_2_5M); 154e7ffd812SXing Zheng else if (speed == 100) 155e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 156e7ffd812SXing Zheng RK3228_GMAC_CLK_25M); 157e7ffd812SXing Zheng else if (speed == 1000) 158e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 159e7ffd812SXing Zheng RK3228_GMAC_CLK_125M); 160e7ffd812SXing Zheng else 161e7ffd812SXing Zheng dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 162e7ffd812SXing Zheng } 163e7ffd812SXing Zheng 164e7ffd812SXing Zheng static void rk3228_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 165e7ffd812SXing Zheng { 166e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 167e7ffd812SXing Zheng 168e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 169e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 170e7ffd812SXing Zheng return; 171e7ffd812SXing Zheng } 172e7ffd812SXing Zheng 173e7ffd812SXing Zheng if (speed == 10) 174e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 175e7ffd812SXing Zheng RK3228_GMAC_RMII_CLK_2_5M | 176e7ffd812SXing Zheng RK3228_GMAC_SPEED_10M); 177e7ffd812SXing Zheng else if (speed == 100) 178e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 179e7ffd812SXing Zheng RK3228_GMAC_RMII_CLK_25M | 180e7ffd812SXing Zheng RK3228_GMAC_SPEED_100M); 181e7ffd812SXing Zheng else 182e7ffd812SXing Zheng dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 183e7ffd812SXing Zheng } 184e7ffd812SXing Zheng 185e7ffd812SXing Zheng static const struct rk_gmac_ops rk3228_ops = { 186e7ffd812SXing Zheng .set_to_rgmii = rk3228_set_to_rgmii, 187e7ffd812SXing Zheng .set_to_rmii = rk3228_set_to_rmii, 188e7ffd812SXing Zheng .set_rgmii_speed = rk3228_set_rgmii_speed, 189e7ffd812SXing Zheng .set_rmii_speed = rk3228_set_rmii_speed, 190e7ffd812SXing Zheng }; 191e7ffd812SXing Zheng 1927ad269eaSRoger Chen #define RK3288_GRF_SOC_CON1 0x0248 1937ad269eaSRoger Chen #define RK3288_GRF_SOC_CON3 0x0250 1947ad269eaSRoger Chen 1957ad269eaSRoger Chen /*RK3288_GRF_SOC_CON1*/ 1960fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(6) | GRF_CLR_BIT(7) | \ 1970fb98db1SHeiko Stübner GRF_CLR_BIT(8)) 1980fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | \ 1990fb98db1SHeiko Stübner GRF_BIT(8)) 2000fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL GRF_BIT(9) 2010fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(9) 2020fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_10M GRF_CLR_BIT(10) 2030fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_100M GRF_BIT(10) 2040fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_25M GRF_BIT(11) 2050fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(11) 2060fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_125M (GRF_CLR_BIT(12) | GRF_CLR_BIT(13)) 2070fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_25M (GRF_BIT(12) | GRF_BIT(13)) 2080fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_2_5M (GRF_CLR_BIT(12) | GRF_BIT(13)) 2090fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE GRF_BIT(14) 2100fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE_CLR GRF_CLR_BIT(14) 2117ad269eaSRoger Chen 2127ad269eaSRoger Chen /*RK3288_GRF_SOC_CON3*/ 2130fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_ENABLE GRF_BIT(14) 2140fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14) 2150fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 2160fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 2170fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 2180fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 2197ad269eaSRoger Chen 2200fb98db1SHeiko Stübner static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv, 2217ad269eaSRoger Chen int tx_delay, int rx_delay) 2227ad269eaSRoger Chen { 2237ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 2247ad269eaSRoger Chen 2257ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 226d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 2277ad269eaSRoger Chen return; 2287ad269eaSRoger Chen } 2297ad269eaSRoger Chen 2307ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 2310fb98db1SHeiko Stübner RK3288_GMAC_PHY_INTF_SEL_RGMII | 2320fb98db1SHeiko Stübner RK3288_GMAC_RMII_MODE_CLR); 2337ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3, 2340fb98db1SHeiko Stübner RK3288_GMAC_RXCLK_DLY_ENABLE | 2350fb98db1SHeiko Stübner RK3288_GMAC_TXCLK_DLY_ENABLE | 2360fb98db1SHeiko Stübner RK3288_GMAC_CLK_RX_DL_CFG(rx_delay) | 2370fb98db1SHeiko Stübner RK3288_GMAC_CLK_TX_DL_CFG(tx_delay)); 2387ad269eaSRoger Chen } 2397ad269eaSRoger Chen 2400fb98db1SHeiko Stübner static void rk3288_set_to_rmii(struct rk_priv_data *bsp_priv) 2417ad269eaSRoger Chen { 2427ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 2437ad269eaSRoger Chen 2447ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 245d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 2467ad269eaSRoger Chen return; 2477ad269eaSRoger Chen } 2487ad269eaSRoger Chen 2497ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 2500fb98db1SHeiko Stübner RK3288_GMAC_PHY_INTF_SEL_RMII | RK3288_GMAC_RMII_MODE); 2517ad269eaSRoger Chen } 2527ad269eaSRoger Chen 2530fb98db1SHeiko Stübner static void rk3288_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 2547ad269eaSRoger Chen { 2557ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 2567ad269eaSRoger Chen 2577ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 258d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 2597ad269eaSRoger Chen return; 2607ad269eaSRoger Chen } 2617ad269eaSRoger Chen 2627ad269eaSRoger Chen if (speed == 10) 2630fb98db1SHeiko Stübner regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 2640fb98db1SHeiko Stübner RK3288_GMAC_CLK_2_5M); 2657ad269eaSRoger Chen else if (speed == 100) 2660fb98db1SHeiko Stübner regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 2670fb98db1SHeiko Stübner RK3288_GMAC_CLK_25M); 2687ad269eaSRoger Chen else if (speed == 1000) 2690fb98db1SHeiko Stübner regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 2700fb98db1SHeiko Stübner RK3288_GMAC_CLK_125M); 2717ad269eaSRoger Chen else 2727ad269eaSRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 2737ad269eaSRoger Chen } 2747ad269eaSRoger Chen 2750fb98db1SHeiko Stübner static void rk3288_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 2767ad269eaSRoger Chen { 2777ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 2787ad269eaSRoger Chen 2797ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 280d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 2817ad269eaSRoger Chen return; 2827ad269eaSRoger Chen } 2837ad269eaSRoger Chen 2847ad269eaSRoger Chen if (speed == 10) { 2857ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 2860fb98db1SHeiko Stübner RK3288_GMAC_RMII_CLK_2_5M | 2870fb98db1SHeiko Stübner RK3288_GMAC_SPEED_10M); 2887ad269eaSRoger Chen } else if (speed == 100) { 2897ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 2900fb98db1SHeiko Stübner RK3288_GMAC_RMII_CLK_25M | 2910fb98db1SHeiko Stübner RK3288_GMAC_SPEED_100M); 2927ad269eaSRoger Chen } else { 2937ad269eaSRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 2947ad269eaSRoger Chen } 2957ad269eaSRoger Chen } 2967ad269eaSRoger Chen 29792c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3288_ops = { 2980fb98db1SHeiko Stübner .set_to_rgmii = rk3288_set_to_rgmii, 2990fb98db1SHeiko Stübner .set_to_rmii = rk3288_set_to_rmii, 3000fb98db1SHeiko Stübner .set_rgmii_speed = rk3288_set_rgmii_speed, 3010fb98db1SHeiko Stübner .set_rmii_speed = rk3288_set_rmii_speed, 3020fb98db1SHeiko Stübner }; 3030fb98db1SHeiko Stübner 304*ba289af8SRoger Chen #define RK3366_GRF_SOC_CON6 0x0418 305*ba289af8SRoger Chen #define RK3366_GRF_SOC_CON7 0x041c 306*ba289af8SRoger Chen 307*ba289af8SRoger Chen /* RK3366_GRF_SOC_CON6 */ 308*ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 309*ba289af8SRoger Chen GRF_CLR_BIT(11)) 310*ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 311*ba289af8SRoger Chen GRF_BIT(11)) 312*ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL GRF_BIT(8) 313*ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 314*ba289af8SRoger Chen #define RK3366_GMAC_SPEED_10M GRF_CLR_BIT(7) 315*ba289af8SRoger Chen #define RK3366_GMAC_SPEED_100M GRF_BIT(7) 316*ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_25M GRF_BIT(3) 317*ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 318*ba289af8SRoger Chen #define RK3366_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 319*ba289af8SRoger Chen #define RK3366_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 320*ba289af8SRoger Chen #define RK3366_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 321*ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE GRF_BIT(6) 322*ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 323*ba289af8SRoger Chen 324*ba289af8SRoger Chen /* RK3366_GRF_SOC_CON7 */ 325*ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 326*ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 327*ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 328*ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 329*ba289af8SRoger Chen #define RK3366_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 330*ba289af8SRoger Chen #define RK3366_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 331*ba289af8SRoger Chen 332*ba289af8SRoger Chen static void rk3366_set_to_rgmii(struct rk_priv_data *bsp_priv, 333*ba289af8SRoger Chen int tx_delay, int rx_delay) 334*ba289af8SRoger Chen { 335*ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 336*ba289af8SRoger Chen 337*ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 338*ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 339*ba289af8SRoger Chen return; 340*ba289af8SRoger Chen } 341*ba289af8SRoger Chen 342*ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 343*ba289af8SRoger Chen RK3366_GMAC_PHY_INTF_SEL_RGMII | 344*ba289af8SRoger Chen RK3366_GMAC_RMII_MODE_CLR); 345*ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON7, 346*ba289af8SRoger Chen RK3366_GMAC_RXCLK_DLY_ENABLE | 347*ba289af8SRoger Chen RK3366_GMAC_TXCLK_DLY_ENABLE | 348*ba289af8SRoger Chen RK3366_GMAC_CLK_RX_DL_CFG(rx_delay) | 349*ba289af8SRoger Chen RK3366_GMAC_CLK_TX_DL_CFG(tx_delay)); 350*ba289af8SRoger Chen } 351*ba289af8SRoger Chen 352*ba289af8SRoger Chen static void rk3366_set_to_rmii(struct rk_priv_data *bsp_priv) 353*ba289af8SRoger Chen { 354*ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 355*ba289af8SRoger Chen 356*ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 357*ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 358*ba289af8SRoger Chen return; 359*ba289af8SRoger Chen } 360*ba289af8SRoger Chen 361*ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 362*ba289af8SRoger Chen RK3366_GMAC_PHY_INTF_SEL_RMII | RK3366_GMAC_RMII_MODE); 363*ba289af8SRoger Chen } 364*ba289af8SRoger Chen 365*ba289af8SRoger Chen static void rk3366_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 366*ba289af8SRoger Chen { 367*ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 368*ba289af8SRoger Chen 369*ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 370*ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 371*ba289af8SRoger Chen return; 372*ba289af8SRoger Chen } 373*ba289af8SRoger Chen 374*ba289af8SRoger Chen if (speed == 10) 375*ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 376*ba289af8SRoger Chen RK3366_GMAC_CLK_2_5M); 377*ba289af8SRoger Chen else if (speed == 100) 378*ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 379*ba289af8SRoger Chen RK3366_GMAC_CLK_25M); 380*ba289af8SRoger Chen else if (speed == 1000) 381*ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 382*ba289af8SRoger Chen RK3366_GMAC_CLK_125M); 383*ba289af8SRoger Chen else 384*ba289af8SRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 385*ba289af8SRoger Chen } 386*ba289af8SRoger Chen 387*ba289af8SRoger Chen static void rk3366_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 388*ba289af8SRoger Chen { 389*ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 390*ba289af8SRoger Chen 391*ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 392*ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 393*ba289af8SRoger Chen return; 394*ba289af8SRoger Chen } 395*ba289af8SRoger Chen 396*ba289af8SRoger Chen if (speed == 10) { 397*ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 398*ba289af8SRoger Chen RK3366_GMAC_RMII_CLK_2_5M | 399*ba289af8SRoger Chen RK3366_GMAC_SPEED_10M); 400*ba289af8SRoger Chen } else if (speed == 100) { 401*ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 402*ba289af8SRoger Chen RK3366_GMAC_RMII_CLK_25M | 403*ba289af8SRoger Chen RK3366_GMAC_SPEED_100M); 404*ba289af8SRoger Chen } else { 405*ba289af8SRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 406*ba289af8SRoger Chen } 407*ba289af8SRoger Chen } 408*ba289af8SRoger Chen 409*ba289af8SRoger Chen static const struct rk_gmac_ops rk3366_ops = { 410*ba289af8SRoger Chen .set_to_rgmii = rk3366_set_to_rgmii, 411*ba289af8SRoger Chen .set_to_rmii = rk3366_set_to_rmii, 412*ba289af8SRoger Chen .set_rgmii_speed = rk3366_set_rgmii_speed, 413*ba289af8SRoger Chen .set_rmii_speed = rk3366_set_rmii_speed, 414*ba289af8SRoger Chen }; 415*ba289af8SRoger Chen 416df558854SHeiko Stübner #define RK3368_GRF_SOC_CON15 0x043c 417df558854SHeiko Stübner #define RK3368_GRF_SOC_CON16 0x0440 418df558854SHeiko Stübner 419df558854SHeiko Stübner /* RK3368_GRF_SOC_CON15 */ 420df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 421df558854SHeiko Stübner GRF_CLR_BIT(11)) 422df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 423df558854SHeiko Stübner GRF_BIT(11)) 424df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL GRF_BIT(8) 425df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 426df558854SHeiko Stübner #define RK3368_GMAC_SPEED_10M GRF_CLR_BIT(7) 427df558854SHeiko Stübner #define RK3368_GMAC_SPEED_100M GRF_BIT(7) 428df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_25M GRF_BIT(3) 429df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 430df558854SHeiko Stübner #define RK3368_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 431df558854SHeiko Stübner #define RK3368_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 432df558854SHeiko Stübner #define RK3368_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 433df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE GRF_BIT(6) 434df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 435df558854SHeiko Stübner 436df558854SHeiko Stübner /* RK3368_GRF_SOC_CON16 */ 437df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 438df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 439df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 440df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 441df558854SHeiko Stübner #define RK3368_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 442df558854SHeiko Stübner #define RK3368_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 443df558854SHeiko Stübner 444df558854SHeiko Stübner static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv, 445df558854SHeiko Stübner int tx_delay, int rx_delay) 446df558854SHeiko Stübner { 447df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 448df558854SHeiko Stübner 449df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 450df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 451df558854SHeiko Stübner return; 452df558854SHeiko Stübner } 453df558854SHeiko Stübner 454df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 455df558854SHeiko Stübner RK3368_GMAC_PHY_INTF_SEL_RGMII | 456df558854SHeiko Stübner RK3368_GMAC_RMII_MODE_CLR); 457df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16, 458df558854SHeiko Stübner RK3368_GMAC_RXCLK_DLY_ENABLE | 459df558854SHeiko Stübner RK3368_GMAC_TXCLK_DLY_ENABLE | 460df558854SHeiko Stübner RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) | 461df558854SHeiko Stübner RK3368_GMAC_CLK_TX_DL_CFG(tx_delay)); 462df558854SHeiko Stübner } 463df558854SHeiko Stübner 464df558854SHeiko Stübner static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv) 465df558854SHeiko Stübner { 466df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 467df558854SHeiko Stübner 468df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 469df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 470df558854SHeiko Stübner return; 471df558854SHeiko Stübner } 472df558854SHeiko Stübner 473df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 474df558854SHeiko Stübner RK3368_GMAC_PHY_INTF_SEL_RMII | RK3368_GMAC_RMII_MODE); 475df558854SHeiko Stübner } 476df558854SHeiko Stübner 477df558854SHeiko Stübner static void rk3368_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 478df558854SHeiko Stübner { 479df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 480df558854SHeiko Stübner 481df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 482df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 483df558854SHeiko Stübner return; 484df558854SHeiko Stübner } 485df558854SHeiko Stübner 486df558854SHeiko Stübner if (speed == 10) 487df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 488df558854SHeiko Stübner RK3368_GMAC_CLK_2_5M); 489df558854SHeiko Stübner else if (speed == 100) 490df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 491df558854SHeiko Stübner RK3368_GMAC_CLK_25M); 492df558854SHeiko Stübner else if (speed == 1000) 493df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 494df558854SHeiko Stübner RK3368_GMAC_CLK_125M); 495df558854SHeiko Stübner else 496df558854SHeiko Stübner dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 497df558854SHeiko Stübner } 498df558854SHeiko Stübner 499df558854SHeiko Stübner static void rk3368_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 500df558854SHeiko Stübner { 501df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 502df558854SHeiko Stübner 503df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 504df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 505df558854SHeiko Stübner return; 506df558854SHeiko Stübner } 507df558854SHeiko Stübner 508df558854SHeiko Stübner if (speed == 10) { 509df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 510df558854SHeiko Stübner RK3368_GMAC_RMII_CLK_2_5M | 511df558854SHeiko Stübner RK3368_GMAC_SPEED_10M); 512df558854SHeiko Stübner } else if (speed == 100) { 513df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 514df558854SHeiko Stübner RK3368_GMAC_RMII_CLK_25M | 515df558854SHeiko Stübner RK3368_GMAC_SPEED_100M); 516df558854SHeiko Stübner } else { 517df558854SHeiko Stübner dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 518df558854SHeiko Stübner } 519df558854SHeiko Stübner } 520df558854SHeiko Stübner 52192c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3368_ops = { 522df558854SHeiko Stübner .set_to_rgmii = rk3368_set_to_rgmii, 523df558854SHeiko Stübner .set_to_rmii = rk3368_set_to_rmii, 524df558854SHeiko Stübner .set_rgmii_speed = rk3368_set_rgmii_speed, 525df558854SHeiko Stübner .set_rmii_speed = rk3368_set_rmii_speed, 526df558854SHeiko Stübner }; 527df558854SHeiko Stübner 528*ba289af8SRoger Chen #define RK3399_GRF_SOC_CON5 0xc214 529*ba289af8SRoger Chen #define RK3399_GRF_SOC_CON6 0xc218 530*ba289af8SRoger Chen 531*ba289af8SRoger Chen /* RK3399_GRF_SOC_CON5 */ 532*ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 533*ba289af8SRoger Chen GRF_CLR_BIT(11)) 534*ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 535*ba289af8SRoger Chen GRF_BIT(11)) 536*ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL GRF_BIT(8) 537*ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 538*ba289af8SRoger Chen #define RK3399_GMAC_SPEED_10M GRF_CLR_BIT(7) 539*ba289af8SRoger Chen #define RK3399_GMAC_SPEED_100M GRF_BIT(7) 540*ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_25M GRF_BIT(3) 541*ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 542*ba289af8SRoger Chen #define RK3399_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 543*ba289af8SRoger Chen #define RK3399_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 544*ba289af8SRoger Chen #define RK3399_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 545*ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE GRF_BIT(6) 546*ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 547*ba289af8SRoger Chen 548*ba289af8SRoger Chen /* RK3399_GRF_SOC_CON6 */ 549*ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 550*ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 551*ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 552*ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 553*ba289af8SRoger Chen #define RK3399_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 554*ba289af8SRoger Chen #define RK3399_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 555*ba289af8SRoger Chen 556*ba289af8SRoger Chen static void rk3399_set_to_rgmii(struct rk_priv_data *bsp_priv, 557*ba289af8SRoger Chen int tx_delay, int rx_delay) 558*ba289af8SRoger Chen { 559*ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 560*ba289af8SRoger Chen 561*ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 562*ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 563*ba289af8SRoger Chen return; 564*ba289af8SRoger Chen } 565*ba289af8SRoger Chen 566*ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 567*ba289af8SRoger Chen RK3399_GMAC_PHY_INTF_SEL_RGMII | 568*ba289af8SRoger Chen RK3399_GMAC_RMII_MODE_CLR); 569*ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON6, 570*ba289af8SRoger Chen RK3399_GMAC_RXCLK_DLY_ENABLE | 571*ba289af8SRoger Chen RK3399_GMAC_TXCLK_DLY_ENABLE | 572*ba289af8SRoger Chen RK3399_GMAC_CLK_RX_DL_CFG(rx_delay) | 573*ba289af8SRoger Chen RK3399_GMAC_CLK_TX_DL_CFG(tx_delay)); 574*ba289af8SRoger Chen } 575*ba289af8SRoger Chen 576*ba289af8SRoger Chen static void rk3399_set_to_rmii(struct rk_priv_data *bsp_priv) 577*ba289af8SRoger Chen { 578*ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 579*ba289af8SRoger Chen 580*ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 581*ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 582*ba289af8SRoger Chen return; 583*ba289af8SRoger Chen } 584*ba289af8SRoger Chen 585*ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 586*ba289af8SRoger Chen RK3399_GMAC_PHY_INTF_SEL_RMII | RK3399_GMAC_RMII_MODE); 587*ba289af8SRoger Chen } 588*ba289af8SRoger Chen 589*ba289af8SRoger Chen static void rk3399_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 590*ba289af8SRoger Chen { 591*ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 592*ba289af8SRoger Chen 593*ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 594*ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 595*ba289af8SRoger Chen return; 596*ba289af8SRoger Chen } 597*ba289af8SRoger Chen 598*ba289af8SRoger Chen if (speed == 10) 599*ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 600*ba289af8SRoger Chen RK3399_GMAC_CLK_2_5M); 601*ba289af8SRoger Chen else if (speed == 100) 602*ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 603*ba289af8SRoger Chen RK3399_GMAC_CLK_25M); 604*ba289af8SRoger Chen else if (speed == 1000) 605*ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 606*ba289af8SRoger Chen RK3399_GMAC_CLK_125M); 607*ba289af8SRoger Chen else 608*ba289af8SRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 609*ba289af8SRoger Chen } 610*ba289af8SRoger Chen 611*ba289af8SRoger Chen static void rk3399_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 612*ba289af8SRoger Chen { 613*ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 614*ba289af8SRoger Chen 615*ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 616*ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 617*ba289af8SRoger Chen return; 618*ba289af8SRoger Chen } 619*ba289af8SRoger Chen 620*ba289af8SRoger Chen if (speed == 10) { 621*ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 622*ba289af8SRoger Chen RK3399_GMAC_RMII_CLK_2_5M | 623*ba289af8SRoger Chen RK3399_GMAC_SPEED_10M); 624*ba289af8SRoger Chen } else if (speed == 100) { 625*ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 626*ba289af8SRoger Chen RK3399_GMAC_RMII_CLK_25M | 627*ba289af8SRoger Chen RK3399_GMAC_SPEED_100M); 628*ba289af8SRoger Chen } else { 629*ba289af8SRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 630*ba289af8SRoger Chen } 631*ba289af8SRoger Chen } 632*ba289af8SRoger Chen 633*ba289af8SRoger Chen static const struct rk_gmac_ops rk3399_ops = { 634*ba289af8SRoger Chen .set_to_rgmii = rk3399_set_to_rgmii, 635*ba289af8SRoger Chen .set_to_rmii = rk3399_set_to_rmii, 636*ba289af8SRoger Chen .set_rgmii_speed = rk3399_set_rgmii_speed, 637*ba289af8SRoger Chen .set_rmii_speed = rk3399_set_rmii_speed, 638*ba289af8SRoger Chen }; 639*ba289af8SRoger Chen 6407ad269eaSRoger Chen static int gmac_clk_init(struct rk_priv_data *bsp_priv) 6417ad269eaSRoger Chen { 6427ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 6437ad269eaSRoger Chen 6447ad269eaSRoger Chen bsp_priv->clk_enabled = false; 6457ad269eaSRoger Chen 6467ad269eaSRoger Chen bsp_priv->mac_clk_rx = devm_clk_get(dev, "mac_clk_rx"); 6477ad269eaSRoger Chen if (IS_ERR(bsp_priv->mac_clk_rx)) 648d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 649d42202dcSRomain Perier "mac_clk_rx"); 6507ad269eaSRoger Chen 6517ad269eaSRoger Chen bsp_priv->mac_clk_tx = devm_clk_get(dev, "mac_clk_tx"); 6527ad269eaSRoger Chen if (IS_ERR(bsp_priv->mac_clk_tx)) 653d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 654d42202dcSRomain Perier "mac_clk_tx"); 6557ad269eaSRoger Chen 6567ad269eaSRoger Chen bsp_priv->aclk_mac = devm_clk_get(dev, "aclk_mac"); 6577ad269eaSRoger Chen if (IS_ERR(bsp_priv->aclk_mac)) 658d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 659d42202dcSRomain Perier "aclk_mac"); 6607ad269eaSRoger Chen 6617ad269eaSRoger Chen bsp_priv->pclk_mac = devm_clk_get(dev, "pclk_mac"); 6627ad269eaSRoger Chen if (IS_ERR(bsp_priv->pclk_mac)) 663d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 664d42202dcSRomain Perier "pclk_mac"); 6657ad269eaSRoger Chen 6667ad269eaSRoger Chen bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth"); 6677ad269eaSRoger Chen if (IS_ERR(bsp_priv->clk_mac)) 668d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 669d42202dcSRomain Perier "stmmaceth"); 6707ad269eaSRoger Chen 6717ad269eaSRoger Chen if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) { 6727ad269eaSRoger Chen bsp_priv->clk_mac_ref = devm_clk_get(dev, "clk_mac_ref"); 6737ad269eaSRoger Chen if (IS_ERR(bsp_priv->clk_mac_ref)) 674d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 675d42202dcSRomain Perier "clk_mac_ref"); 6767ad269eaSRoger Chen 6777ad269eaSRoger Chen if (!bsp_priv->clock_input) { 6787ad269eaSRoger Chen bsp_priv->clk_mac_refout = 6797ad269eaSRoger Chen devm_clk_get(dev, "clk_mac_refout"); 6807ad269eaSRoger Chen if (IS_ERR(bsp_priv->clk_mac_refout)) 681d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 682d42202dcSRomain Perier "clk_mac_refout"); 6837ad269eaSRoger Chen } 6847ad269eaSRoger Chen } 6857ad269eaSRoger Chen 6867ad269eaSRoger Chen if (bsp_priv->clock_input) { 687d42202dcSRomain Perier dev_info(dev, "clock input from PHY\n"); 6887ad269eaSRoger Chen } else { 6897ad269eaSRoger Chen if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) 690c48fa33cSHeiko Stübner clk_set_rate(bsp_priv->clk_mac, 50000000); 6917ad269eaSRoger Chen } 6927ad269eaSRoger Chen 6937ad269eaSRoger Chen return 0; 6947ad269eaSRoger Chen } 6957ad269eaSRoger Chen 6967ad269eaSRoger Chen static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable) 6977ad269eaSRoger Chen { 698428ad1bcSLABBE Corentin int phy_iface = bsp_priv->phy_iface; 6997ad269eaSRoger Chen 7007ad269eaSRoger Chen if (enable) { 7017ad269eaSRoger Chen if (!bsp_priv->clk_enabled) { 7027ad269eaSRoger Chen if (phy_iface == PHY_INTERFACE_MODE_RMII) { 7037ad269eaSRoger Chen if (!IS_ERR(bsp_priv->mac_clk_rx)) 7047ad269eaSRoger Chen clk_prepare_enable( 7057ad269eaSRoger Chen bsp_priv->mac_clk_rx); 7067ad269eaSRoger Chen 7077ad269eaSRoger Chen if (!IS_ERR(bsp_priv->clk_mac_ref)) 7087ad269eaSRoger Chen clk_prepare_enable( 7097ad269eaSRoger Chen bsp_priv->clk_mac_ref); 7107ad269eaSRoger Chen 7117ad269eaSRoger Chen if (!IS_ERR(bsp_priv->clk_mac_refout)) 7127ad269eaSRoger Chen clk_prepare_enable( 7137ad269eaSRoger Chen bsp_priv->clk_mac_refout); 7147ad269eaSRoger Chen } 7157ad269eaSRoger Chen 7167ad269eaSRoger Chen if (!IS_ERR(bsp_priv->aclk_mac)) 7177ad269eaSRoger Chen clk_prepare_enable(bsp_priv->aclk_mac); 7187ad269eaSRoger Chen 7197ad269eaSRoger Chen if (!IS_ERR(bsp_priv->pclk_mac)) 7207ad269eaSRoger Chen clk_prepare_enable(bsp_priv->pclk_mac); 7217ad269eaSRoger Chen 7227ad269eaSRoger Chen if (!IS_ERR(bsp_priv->mac_clk_tx)) 7237ad269eaSRoger Chen clk_prepare_enable(bsp_priv->mac_clk_tx); 7247ad269eaSRoger Chen 7257ad269eaSRoger Chen /** 7267ad269eaSRoger Chen * if (!IS_ERR(bsp_priv->clk_mac)) 7277ad269eaSRoger Chen * clk_prepare_enable(bsp_priv->clk_mac); 7287ad269eaSRoger Chen */ 7297ad269eaSRoger Chen mdelay(5); 7307ad269eaSRoger Chen bsp_priv->clk_enabled = true; 7317ad269eaSRoger Chen } 7327ad269eaSRoger Chen } else { 7337ad269eaSRoger Chen if (bsp_priv->clk_enabled) { 7347ad269eaSRoger Chen if (phy_iface == PHY_INTERFACE_MODE_RMII) { 7357ad269eaSRoger Chen if (!IS_ERR(bsp_priv->mac_clk_rx)) 7367ad269eaSRoger Chen clk_disable_unprepare( 7377ad269eaSRoger Chen bsp_priv->mac_clk_rx); 7387ad269eaSRoger Chen 7397ad269eaSRoger Chen if (!IS_ERR(bsp_priv->clk_mac_ref)) 7407ad269eaSRoger Chen clk_disable_unprepare( 7417ad269eaSRoger Chen bsp_priv->clk_mac_ref); 7427ad269eaSRoger Chen 7437ad269eaSRoger Chen if (!IS_ERR(bsp_priv->clk_mac_refout)) 7447ad269eaSRoger Chen clk_disable_unprepare( 7457ad269eaSRoger Chen bsp_priv->clk_mac_refout); 7467ad269eaSRoger Chen } 7477ad269eaSRoger Chen 7487ad269eaSRoger Chen if (!IS_ERR(bsp_priv->aclk_mac)) 7497ad269eaSRoger Chen clk_disable_unprepare(bsp_priv->aclk_mac); 7507ad269eaSRoger Chen 7517ad269eaSRoger Chen if (!IS_ERR(bsp_priv->pclk_mac)) 7527ad269eaSRoger Chen clk_disable_unprepare(bsp_priv->pclk_mac); 7537ad269eaSRoger Chen 7547ad269eaSRoger Chen if (!IS_ERR(bsp_priv->mac_clk_tx)) 7557ad269eaSRoger Chen clk_disable_unprepare(bsp_priv->mac_clk_tx); 7567ad269eaSRoger Chen /** 7577ad269eaSRoger Chen * if (!IS_ERR(bsp_priv->clk_mac)) 7587ad269eaSRoger Chen * clk_disable_unprepare(bsp_priv->clk_mac); 7597ad269eaSRoger Chen */ 7607ad269eaSRoger Chen bsp_priv->clk_enabled = false; 7617ad269eaSRoger Chen } 7627ad269eaSRoger Chen } 7637ad269eaSRoger Chen 7647ad269eaSRoger Chen return 0; 7657ad269eaSRoger Chen } 7667ad269eaSRoger Chen 7677ad269eaSRoger Chen static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable) 7687ad269eaSRoger Chen { 7692e12f536SRomain Perier struct regulator *ldo = bsp_priv->regulator; 7707ad269eaSRoger Chen int ret; 7717ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 7727ad269eaSRoger Chen 7732e12f536SRomain Perier if (!ldo) { 774d42202dcSRomain Perier dev_err(dev, "no regulator found\n"); 7757ad269eaSRoger Chen return -1; 7767ad269eaSRoger Chen } 7777ad269eaSRoger Chen 7787ad269eaSRoger Chen if (enable) { 7797ad269eaSRoger Chen ret = regulator_enable(ldo); 7802e12f536SRomain Perier if (ret) 781d42202dcSRomain Perier dev_err(dev, "fail to enable phy-supply\n"); 7827ad269eaSRoger Chen } else { 7837ad269eaSRoger Chen ret = regulator_disable(ldo); 7842e12f536SRomain Perier if (ret) 785d42202dcSRomain Perier dev_err(dev, "fail to disable phy-supply\n"); 7867ad269eaSRoger Chen } 7877ad269eaSRoger Chen 7887ad269eaSRoger Chen return 0; 7897ad269eaSRoger Chen } 7907ad269eaSRoger Chen 7910fb98db1SHeiko Stübner static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev, 79292c2588fSJoachim Eastwood const struct rk_gmac_ops *ops) 7937ad269eaSRoger Chen { 7947ad269eaSRoger Chen struct rk_priv_data *bsp_priv; 7957ad269eaSRoger Chen struct device *dev = &pdev->dev; 7967ad269eaSRoger Chen int ret; 7977ad269eaSRoger Chen const char *strings = NULL; 7987ad269eaSRoger Chen int value; 7997ad269eaSRoger Chen 8007ad269eaSRoger Chen bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL); 8017ad269eaSRoger Chen if (!bsp_priv) 8027ad269eaSRoger Chen return ERR_PTR(-ENOMEM); 8037ad269eaSRoger Chen 8047ad269eaSRoger Chen bsp_priv->phy_iface = of_get_phy_mode(dev->of_node); 8050fb98db1SHeiko Stübner bsp_priv->ops = ops; 8067ad269eaSRoger Chen 8072e12f536SRomain Perier bsp_priv->regulator = devm_regulator_get_optional(dev, "phy"); 8082e12f536SRomain Perier if (IS_ERR(bsp_priv->regulator)) { 8092e12f536SRomain Perier if (PTR_ERR(bsp_priv->regulator) == -EPROBE_DEFER) { 8102e12f536SRomain Perier dev_err(dev, "phy regulator is not available yet, deferred probing\n"); 8112e12f536SRomain Perier return ERR_PTR(-EPROBE_DEFER); 8122e12f536SRomain Perier } 8132e12f536SRomain Perier dev_err(dev, "no regulator found\n"); 8142e12f536SRomain Perier bsp_priv->regulator = NULL; 8157ad269eaSRoger Chen } 8167ad269eaSRoger Chen 8177ad269eaSRoger Chen ret = of_property_read_string(dev->of_node, "clock_in_out", &strings); 8187ad269eaSRoger Chen if (ret) { 819d42202dcSRomain Perier dev_err(dev, "Can not read property: clock_in_out.\n"); 8207ad269eaSRoger Chen bsp_priv->clock_input = true; 8217ad269eaSRoger Chen } else { 822d42202dcSRomain Perier dev_info(dev, "clock input or output? (%s).\n", 823d42202dcSRomain Perier strings); 8247ad269eaSRoger Chen if (!strcmp(strings, "input")) 8257ad269eaSRoger Chen bsp_priv->clock_input = true; 8267ad269eaSRoger Chen else 8277ad269eaSRoger Chen bsp_priv->clock_input = false; 8287ad269eaSRoger Chen } 8297ad269eaSRoger Chen 8307ad269eaSRoger Chen ret = of_property_read_u32(dev->of_node, "tx_delay", &value); 8317ad269eaSRoger Chen if (ret) { 8327ad269eaSRoger Chen bsp_priv->tx_delay = 0x30; 833d42202dcSRomain Perier dev_err(dev, "Can not read property: tx_delay."); 834d42202dcSRomain Perier dev_err(dev, "set tx_delay to 0x%x\n", 835d42202dcSRomain Perier bsp_priv->tx_delay); 8367ad269eaSRoger Chen } else { 837d42202dcSRomain Perier dev_info(dev, "TX delay(0x%x).\n", value); 8387ad269eaSRoger Chen bsp_priv->tx_delay = value; 8397ad269eaSRoger Chen } 8407ad269eaSRoger Chen 8417ad269eaSRoger Chen ret = of_property_read_u32(dev->of_node, "rx_delay", &value); 8427ad269eaSRoger Chen if (ret) { 8437ad269eaSRoger Chen bsp_priv->rx_delay = 0x10; 844d42202dcSRomain Perier dev_err(dev, "Can not read property: rx_delay."); 845d42202dcSRomain Perier dev_err(dev, "set rx_delay to 0x%x\n", 846d42202dcSRomain Perier bsp_priv->rx_delay); 8477ad269eaSRoger Chen } else { 848d42202dcSRomain Perier dev_info(dev, "RX delay(0x%x).\n", value); 8497ad269eaSRoger Chen bsp_priv->rx_delay = value; 8507ad269eaSRoger Chen } 8517ad269eaSRoger Chen 8527ad269eaSRoger Chen bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node, 8537ad269eaSRoger Chen "rockchip,grf"); 8547ad269eaSRoger Chen bsp_priv->pdev = pdev; 8557ad269eaSRoger Chen 8567ad269eaSRoger Chen /*rmii or rgmii*/ 8577ad269eaSRoger Chen if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RGMII) { 858d42202dcSRomain Perier dev_info(dev, "init for RGMII\n"); 8590fb98db1SHeiko Stübner bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 8600fb98db1SHeiko Stübner bsp_priv->rx_delay); 8617ad269eaSRoger Chen } else if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) { 862d42202dcSRomain Perier dev_info(dev, "init for RMII\n"); 8630fb98db1SHeiko Stübner bsp_priv->ops->set_to_rmii(bsp_priv); 8647ad269eaSRoger Chen } else { 865d42202dcSRomain Perier dev_err(dev, "NO interface defined!\n"); 8667ad269eaSRoger Chen } 8677ad269eaSRoger Chen 8687ad269eaSRoger Chen gmac_clk_init(bsp_priv); 8697ad269eaSRoger Chen 8707ad269eaSRoger Chen return bsp_priv; 8717ad269eaSRoger Chen } 8727ad269eaSRoger Chen 873229666c1SVincent Palatin static int rk_gmac_powerup(struct rk_priv_data *bsp_priv) 8747ad269eaSRoger Chen { 8757ad269eaSRoger Chen int ret; 8767ad269eaSRoger Chen 8777ad269eaSRoger Chen ret = phy_power_on(bsp_priv, true); 8787ad269eaSRoger Chen if (ret) 8797ad269eaSRoger Chen return ret; 8807ad269eaSRoger Chen 8817ad269eaSRoger Chen ret = gmac_clk_enable(bsp_priv, true); 8827ad269eaSRoger Chen if (ret) 8837ad269eaSRoger Chen return ret; 8847ad269eaSRoger Chen 8857ad269eaSRoger Chen return 0; 8867ad269eaSRoger Chen } 8877ad269eaSRoger Chen 888229666c1SVincent Palatin static void rk_gmac_powerdown(struct rk_priv_data *gmac) 8897ad269eaSRoger Chen { 8907ad269eaSRoger Chen phy_power_on(gmac, false); 8917ad269eaSRoger Chen gmac_clk_enable(gmac, false); 8927ad269eaSRoger Chen } 8937ad269eaSRoger Chen 894229666c1SVincent Palatin static int rk_gmac_init(struct platform_device *pdev, void *priv) 895229666c1SVincent Palatin { 896229666c1SVincent Palatin struct rk_priv_data *bsp_priv = priv; 897229666c1SVincent Palatin 898229666c1SVincent Palatin return rk_gmac_powerup(bsp_priv); 899229666c1SVincent Palatin } 900229666c1SVincent Palatin 901229666c1SVincent Palatin static void rk_gmac_exit(struct platform_device *pdev, void *priv) 902229666c1SVincent Palatin { 903229666c1SVincent Palatin struct rk_priv_data *bsp_priv = priv; 904229666c1SVincent Palatin 905229666c1SVincent Palatin rk_gmac_powerdown(bsp_priv); 906229666c1SVincent Palatin } 907229666c1SVincent Palatin 908229666c1SVincent Palatin static void rk_gmac_suspend(struct platform_device *pdev, void *priv) 909229666c1SVincent Palatin { 910229666c1SVincent Palatin struct rk_priv_data *bsp_priv = priv; 911229666c1SVincent Palatin 912229666c1SVincent Palatin /* Keep the PHY up if we use Wake-on-Lan. */ 913229666c1SVincent Palatin if (device_may_wakeup(&pdev->dev)) 914229666c1SVincent Palatin return; 915229666c1SVincent Palatin 916229666c1SVincent Palatin rk_gmac_powerdown(bsp_priv); 917229666c1SVincent Palatin bsp_priv->suspended = true; 918229666c1SVincent Palatin } 919229666c1SVincent Palatin 920229666c1SVincent Palatin static void rk_gmac_resume(struct platform_device *pdev, void *priv) 921229666c1SVincent Palatin { 922229666c1SVincent Palatin struct rk_priv_data *bsp_priv = priv; 923229666c1SVincent Palatin 924229666c1SVincent Palatin /* The PHY was up for Wake-on-Lan. */ 925229666c1SVincent Palatin if (!bsp_priv->suspended) 926229666c1SVincent Palatin return; 927229666c1SVincent Palatin 928229666c1SVincent Palatin rk_gmac_powerup(bsp_priv); 929229666c1SVincent Palatin bsp_priv->suspended = false; 930229666c1SVincent Palatin } 931229666c1SVincent Palatin 9327ad269eaSRoger Chen static void rk_fix_speed(void *priv, unsigned int speed) 9337ad269eaSRoger Chen { 9347ad269eaSRoger Chen struct rk_priv_data *bsp_priv = priv; 9357ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 9367ad269eaSRoger Chen 9377ad269eaSRoger Chen if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RGMII) 9380fb98db1SHeiko Stübner bsp_priv->ops->set_rgmii_speed(bsp_priv, speed); 9397ad269eaSRoger Chen else if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) 9400fb98db1SHeiko Stübner bsp_priv->ops->set_rmii_speed(bsp_priv, speed); 9417ad269eaSRoger Chen else 9427ad269eaSRoger Chen dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface); 9437ad269eaSRoger Chen } 9447ad269eaSRoger Chen 94527ffefd2SJoachim Eastwood static int rk_gmac_probe(struct platform_device *pdev) 94627ffefd2SJoachim Eastwood { 94727ffefd2SJoachim Eastwood struct plat_stmmacenet_data *plat_dat; 94827ffefd2SJoachim Eastwood struct stmmac_resources stmmac_res; 949f529f182SJoachim Eastwood const struct rk_gmac_ops *data; 95027ffefd2SJoachim Eastwood int ret; 95127ffefd2SJoachim Eastwood 952149adeddSJoachim Eastwood data = of_device_get_match_data(&pdev->dev); 953149adeddSJoachim Eastwood if (!data) { 954149adeddSJoachim Eastwood dev_err(&pdev->dev, "no of match data provided\n"); 955149adeddSJoachim Eastwood return -EINVAL; 956149adeddSJoachim Eastwood } 957149adeddSJoachim Eastwood 95827ffefd2SJoachim Eastwood ret = stmmac_get_platform_resources(pdev, &stmmac_res); 95927ffefd2SJoachim Eastwood if (ret) 96027ffefd2SJoachim Eastwood return ret; 96127ffefd2SJoachim Eastwood 96227ffefd2SJoachim Eastwood plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac); 96327ffefd2SJoachim Eastwood if (IS_ERR(plat_dat)) 96427ffefd2SJoachim Eastwood return PTR_ERR(plat_dat); 96527ffefd2SJoachim Eastwood 96627ffefd2SJoachim Eastwood plat_dat->has_gmac = true; 96727ffefd2SJoachim Eastwood plat_dat->init = rk_gmac_init; 96827ffefd2SJoachim Eastwood plat_dat->exit = rk_gmac_exit; 96927ffefd2SJoachim Eastwood plat_dat->fix_mac_speed = rk_fix_speed; 970229666c1SVincent Palatin plat_dat->suspend = rk_gmac_suspend; 971229666c1SVincent Palatin plat_dat->resume = rk_gmac_resume; 97227ffefd2SJoachim Eastwood 973f529f182SJoachim Eastwood plat_dat->bsp_priv = rk_gmac_setup(pdev, data); 97427ffefd2SJoachim Eastwood if (IS_ERR(plat_dat->bsp_priv)) 97527ffefd2SJoachim Eastwood return PTR_ERR(plat_dat->bsp_priv); 97627ffefd2SJoachim Eastwood 97727ffefd2SJoachim Eastwood ret = rk_gmac_init(pdev, plat_dat->bsp_priv); 97827ffefd2SJoachim Eastwood if (ret) 97927ffefd2SJoachim Eastwood return ret; 98027ffefd2SJoachim Eastwood 98127ffefd2SJoachim Eastwood return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); 98227ffefd2SJoachim Eastwood } 98327ffefd2SJoachim Eastwood 984e0fb4013SJoachim Eastwood static const struct of_device_id rk_gmac_dwmac_match[] = { 985e7ffd812SXing Zheng { .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops }, 986f529f182SJoachim Eastwood { .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops }, 987*ba289af8SRoger Chen { .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops }, 988f529f182SJoachim Eastwood { .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops }, 989*ba289af8SRoger Chen { .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops }, 990e0fb4013SJoachim Eastwood { } 991e0fb4013SJoachim Eastwood }; 992e0fb4013SJoachim Eastwood MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match); 993e0fb4013SJoachim Eastwood 994e0fb4013SJoachim Eastwood static struct platform_driver rk_gmac_dwmac_driver = { 99527ffefd2SJoachim Eastwood .probe = rk_gmac_probe, 996e0fb4013SJoachim Eastwood .remove = stmmac_pltfr_remove, 997e0fb4013SJoachim Eastwood .driver = { 998e0fb4013SJoachim Eastwood .name = "rk_gmac-dwmac", 999e0fb4013SJoachim Eastwood .pm = &stmmac_pltfr_pm_ops, 1000e0fb4013SJoachim Eastwood .of_match_table = rk_gmac_dwmac_match, 1001e0fb4013SJoachim Eastwood }, 1002e0fb4013SJoachim Eastwood }; 1003e0fb4013SJoachim Eastwood module_platform_driver(rk_gmac_dwmac_driver); 1004e0fb4013SJoachim Eastwood 1005e0fb4013SJoachim Eastwood MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>"); 1006e0fb4013SJoachim Eastwood MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer"); 1007e0fb4013SJoachim Eastwood MODULE_LICENSE("GPL"); 1008