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> 332c896fb0SDavid Wu #include <linux/pm_runtime.h> 347ad269eaSRoger Chen 35e0fb4013SJoachim Eastwood #include "stmmac_platform.h" 36e0fb4013SJoachim Eastwood 370fb98db1SHeiko Stübner struct rk_priv_data; 380fb98db1SHeiko Stübner struct rk_gmac_ops { 390fb98db1SHeiko Stübner void (*set_to_rgmii)(struct rk_priv_data *bsp_priv, 400fb98db1SHeiko Stübner int tx_delay, int rx_delay); 410fb98db1SHeiko Stübner void (*set_to_rmii)(struct rk_priv_data *bsp_priv); 420fb98db1SHeiko Stübner void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed); 430fb98db1SHeiko Stübner void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed); 440fb98db1SHeiko Stübner }; 450fb98db1SHeiko Stübner 467ad269eaSRoger Chen struct rk_priv_data { 477ad269eaSRoger Chen struct platform_device *pdev; 487ad269eaSRoger Chen int phy_iface; 492e12f536SRomain Perier struct regulator *regulator; 50229666c1SVincent Palatin bool suspended; 5192c2588fSJoachim Eastwood const struct rk_gmac_ops *ops; 527ad269eaSRoger Chen 537ad269eaSRoger Chen bool clk_enabled; 547ad269eaSRoger Chen bool clock_input; 557ad269eaSRoger Chen 567ad269eaSRoger Chen struct clk *clk_mac; 577ad269eaSRoger Chen struct clk *gmac_clkin; 587ad269eaSRoger Chen struct clk *mac_clk_rx; 597ad269eaSRoger Chen struct clk *mac_clk_tx; 607ad269eaSRoger Chen struct clk *clk_mac_ref; 617ad269eaSRoger Chen struct clk *clk_mac_refout; 627ad269eaSRoger Chen struct clk *aclk_mac; 637ad269eaSRoger Chen struct clk *pclk_mac; 647ad269eaSRoger Chen 657ad269eaSRoger Chen int tx_delay; 667ad269eaSRoger Chen int rx_delay; 677ad269eaSRoger Chen 687ad269eaSRoger Chen struct regmap *grf; 697ad269eaSRoger Chen }; 707ad269eaSRoger Chen 717ad269eaSRoger Chen #define HIWORD_UPDATE(val, mask, shift) \ 727ad269eaSRoger Chen ((val) << (shift) | (mask) << ((shift) + 16)) 737ad269eaSRoger Chen 747ad269eaSRoger Chen #define GRF_BIT(nr) (BIT(nr) | BIT(nr+16)) 757ad269eaSRoger Chen #define GRF_CLR_BIT(nr) (BIT(nr+16)) 767ad269eaSRoger Chen 77e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON0 0x0900 78e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON1 0x0904 79e7ffd812SXing Zheng 80e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON0 */ 81e7ffd812SXing Zheng #define RK3228_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 82e7ffd812SXing Zheng #define RK3228_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 83e7ffd812SXing Zheng 84e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON1 */ 85e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RGMII \ 86e7ffd812SXing Zheng (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6)) 87e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RMII \ 88e7ffd812SXing Zheng (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6)) 89e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL GRF_BIT(3) 90e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 91e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_10M GRF_CLR_BIT(2) 92e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_100M GRF_BIT(2) 93e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_25M GRF_BIT(7) 94e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7) 95e7ffd812SXing Zheng #define RK3228_GMAC_CLK_125M (GRF_CLR_BIT(8) | GRF_CLR_BIT(9)) 96e7ffd812SXing Zheng #define RK3228_GMAC_CLK_25M (GRF_BIT(8) | GRF_BIT(9)) 97e7ffd812SXing Zheng #define RK3228_GMAC_CLK_2_5M (GRF_CLR_BIT(8) | GRF_BIT(9)) 98e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE GRF_BIT(10) 99e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE_CLR GRF_CLR_BIT(10) 100e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0) 101e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0) 102e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1) 103e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(1) 104e7ffd812SXing Zheng 105e7ffd812SXing Zheng static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv, 106e7ffd812SXing Zheng int tx_delay, int rx_delay) 107e7ffd812SXing Zheng { 108e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 109e7ffd812SXing Zheng 110e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 111e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 112e7ffd812SXing Zheng return; 113e7ffd812SXing Zheng } 114e7ffd812SXing Zheng 115e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 116e7ffd812SXing Zheng RK3228_GMAC_PHY_INTF_SEL_RGMII | 117e7ffd812SXing Zheng RK3228_GMAC_RMII_MODE_CLR | 118e7ffd812SXing Zheng RK3228_GMAC_RXCLK_DLY_ENABLE | 119e7ffd812SXing Zheng RK3228_GMAC_TXCLK_DLY_ENABLE); 120e7ffd812SXing Zheng 121e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON0, 122e7ffd812SXing Zheng RK3228_GMAC_CLK_RX_DL_CFG(rx_delay) | 123e7ffd812SXing Zheng RK3228_GMAC_CLK_TX_DL_CFG(tx_delay)); 124e7ffd812SXing Zheng } 125e7ffd812SXing Zheng 126e7ffd812SXing Zheng static void rk3228_set_to_rmii(struct rk_priv_data *bsp_priv) 127e7ffd812SXing Zheng { 128e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 129e7ffd812SXing Zheng 130e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 131e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 132e7ffd812SXing Zheng return; 133e7ffd812SXing Zheng } 134e7ffd812SXing Zheng 135e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 136e7ffd812SXing Zheng RK3228_GMAC_PHY_INTF_SEL_RMII | 137e7ffd812SXing Zheng RK3228_GMAC_RMII_MODE); 138e7ffd812SXing Zheng 139e7ffd812SXing Zheng /* set MAC to RMII mode */ 140e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, GRF_BIT(11)); 141e7ffd812SXing Zheng } 142e7ffd812SXing Zheng 143e7ffd812SXing Zheng static void rk3228_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 144e7ffd812SXing Zheng { 145e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 146e7ffd812SXing Zheng 147e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 148e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 149e7ffd812SXing Zheng return; 150e7ffd812SXing Zheng } 151e7ffd812SXing Zheng 152e7ffd812SXing Zheng if (speed == 10) 153e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 154e7ffd812SXing Zheng RK3228_GMAC_CLK_2_5M); 155e7ffd812SXing Zheng else if (speed == 100) 156e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 157e7ffd812SXing Zheng RK3228_GMAC_CLK_25M); 158e7ffd812SXing Zheng else if (speed == 1000) 159e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 160e7ffd812SXing Zheng RK3228_GMAC_CLK_125M); 161e7ffd812SXing Zheng else 162e7ffd812SXing Zheng dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 163e7ffd812SXing Zheng } 164e7ffd812SXing Zheng 165e7ffd812SXing Zheng static void rk3228_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 166e7ffd812SXing Zheng { 167e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 168e7ffd812SXing Zheng 169e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 170e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 171e7ffd812SXing Zheng return; 172e7ffd812SXing Zheng } 173e7ffd812SXing Zheng 174e7ffd812SXing Zheng if (speed == 10) 175e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 176e7ffd812SXing Zheng RK3228_GMAC_RMII_CLK_2_5M | 177e7ffd812SXing Zheng RK3228_GMAC_SPEED_10M); 178e7ffd812SXing Zheng else if (speed == 100) 179e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 180e7ffd812SXing Zheng RK3228_GMAC_RMII_CLK_25M | 181e7ffd812SXing Zheng RK3228_GMAC_SPEED_100M); 182e7ffd812SXing Zheng else 183e7ffd812SXing Zheng dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 184e7ffd812SXing Zheng } 185e7ffd812SXing Zheng 186e7ffd812SXing Zheng static const struct rk_gmac_ops rk3228_ops = { 187e7ffd812SXing Zheng .set_to_rgmii = rk3228_set_to_rgmii, 188e7ffd812SXing Zheng .set_to_rmii = rk3228_set_to_rmii, 189e7ffd812SXing Zheng .set_rgmii_speed = rk3228_set_rgmii_speed, 190e7ffd812SXing Zheng .set_rmii_speed = rk3228_set_rmii_speed, 191e7ffd812SXing Zheng }; 192e7ffd812SXing Zheng 1937ad269eaSRoger Chen #define RK3288_GRF_SOC_CON1 0x0248 1947ad269eaSRoger Chen #define RK3288_GRF_SOC_CON3 0x0250 1957ad269eaSRoger Chen 1967ad269eaSRoger Chen /*RK3288_GRF_SOC_CON1*/ 1970fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(6) | GRF_CLR_BIT(7) | \ 1980fb98db1SHeiko Stübner GRF_CLR_BIT(8)) 1990fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | \ 2000fb98db1SHeiko Stübner GRF_BIT(8)) 2010fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL GRF_BIT(9) 2020fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(9) 2030fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_10M GRF_CLR_BIT(10) 2040fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_100M GRF_BIT(10) 2050fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_25M GRF_BIT(11) 2060fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(11) 2070fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_125M (GRF_CLR_BIT(12) | GRF_CLR_BIT(13)) 2080fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_25M (GRF_BIT(12) | GRF_BIT(13)) 2090fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_2_5M (GRF_CLR_BIT(12) | GRF_BIT(13)) 2100fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE GRF_BIT(14) 2110fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE_CLR GRF_CLR_BIT(14) 2127ad269eaSRoger Chen 2137ad269eaSRoger Chen /*RK3288_GRF_SOC_CON3*/ 2140fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_ENABLE GRF_BIT(14) 2150fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14) 2160fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 2170fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 2180fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 2190fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 2207ad269eaSRoger Chen 2210fb98db1SHeiko Stübner static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv, 2227ad269eaSRoger Chen int tx_delay, int rx_delay) 2237ad269eaSRoger Chen { 2247ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 2257ad269eaSRoger Chen 2267ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 227d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 2287ad269eaSRoger Chen return; 2297ad269eaSRoger Chen } 2307ad269eaSRoger Chen 2317ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 2320fb98db1SHeiko Stübner RK3288_GMAC_PHY_INTF_SEL_RGMII | 2330fb98db1SHeiko Stübner RK3288_GMAC_RMII_MODE_CLR); 2347ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3, 2350fb98db1SHeiko Stübner RK3288_GMAC_RXCLK_DLY_ENABLE | 2360fb98db1SHeiko Stübner RK3288_GMAC_TXCLK_DLY_ENABLE | 2370fb98db1SHeiko Stübner RK3288_GMAC_CLK_RX_DL_CFG(rx_delay) | 2380fb98db1SHeiko Stübner RK3288_GMAC_CLK_TX_DL_CFG(tx_delay)); 2397ad269eaSRoger Chen } 2407ad269eaSRoger Chen 2410fb98db1SHeiko Stübner static void rk3288_set_to_rmii(struct rk_priv_data *bsp_priv) 2427ad269eaSRoger Chen { 2437ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 2447ad269eaSRoger Chen 2457ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 246d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 2477ad269eaSRoger Chen return; 2487ad269eaSRoger Chen } 2497ad269eaSRoger Chen 2507ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 2510fb98db1SHeiko Stübner RK3288_GMAC_PHY_INTF_SEL_RMII | RK3288_GMAC_RMII_MODE); 2527ad269eaSRoger Chen } 2537ad269eaSRoger Chen 2540fb98db1SHeiko Stübner static void rk3288_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 2557ad269eaSRoger Chen { 2567ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 2577ad269eaSRoger Chen 2587ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 259d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 2607ad269eaSRoger Chen return; 2617ad269eaSRoger Chen } 2627ad269eaSRoger Chen 2637ad269eaSRoger Chen if (speed == 10) 2640fb98db1SHeiko Stübner regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 2650fb98db1SHeiko Stübner RK3288_GMAC_CLK_2_5M); 2667ad269eaSRoger Chen else if (speed == 100) 2670fb98db1SHeiko Stübner regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 2680fb98db1SHeiko Stübner RK3288_GMAC_CLK_25M); 2697ad269eaSRoger Chen else if (speed == 1000) 2700fb98db1SHeiko Stübner regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 2710fb98db1SHeiko Stübner RK3288_GMAC_CLK_125M); 2727ad269eaSRoger Chen else 2737ad269eaSRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 2747ad269eaSRoger Chen } 2757ad269eaSRoger Chen 2760fb98db1SHeiko Stübner static void rk3288_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 2777ad269eaSRoger Chen { 2787ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 2797ad269eaSRoger Chen 2807ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 281d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 2827ad269eaSRoger Chen return; 2837ad269eaSRoger Chen } 2847ad269eaSRoger Chen 2857ad269eaSRoger Chen if (speed == 10) { 2867ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 2870fb98db1SHeiko Stübner RK3288_GMAC_RMII_CLK_2_5M | 2880fb98db1SHeiko Stübner RK3288_GMAC_SPEED_10M); 2897ad269eaSRoger Chen } else if (speed == 100) { 2907ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 2910fb98db1SHeiko Stübner RK3288_GMAC_RMII_CLK_25M | 2920fb98db1SHeiko Stübner RK3288_GMAC_SPEED_100M); 2937ad269eaSRoger Chen } else { 2947ad269eaSRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 2957ad269eaSRoger Chen } 2967ad269eaSRoger Chen } 2977ad269eaSRoger Chen 29892c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3288_ops = { 2990fb98db1SHeiko Stübner .set_to_rgmii = rk3288_set_to_rgmii, 3000fb98db1SHeiko Stübner .set_to_rmii = rk3288_set_to_rmii, 3010fb98db1SHeiko Stübner .set_rgmii_speed = rk3288_set_rgmii_speed, 3020fb98db1SHeiko Stübner .set_rmii_speed = rk3288_set_rmii_speed, 3030fb98db1SHeiko Stübner }; 3040fb98db1SHeiko Stübner 305ba289af8SRoger Chen #define RK3366_GRF_SOC_CON6 0x0418 306ba289af8SRoger Chen #define RK3366_GRF_SOC_CON7 0x041c 307ba289af8SRoger Chen 308ba289af8SRoger Chen /* RK3366_GRF_SOC_CON6 */ 309ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 310ba289af8SRoger Chen GRF_CLR_BIT(11)) 311ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 312ba289af8SRoger Chen GRF_BIT(11)) 313ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL GRF_BIT(8) 314ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 315ba289af8SRoger Chen #define RK3366_GMAC_SPEED_10M GRF_CLR_BIT(7) 316ba289af8SRoger Chen #define RK3366_GMAC_SPEED_100M GRF_BIT(7) 317ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_25M GRF_BIT(3) 318ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 319ba289af8SRoger Chen #define RK3366_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 320ba289af8SRoger Chen #define RK3366_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 321ba289af8SRoger Chen #define RK3366_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 322ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE GRF_BIT(6) 323ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 324ba289af8SRoger Chen 325ba289af8SRoger Chen /* RK3366_GRF_SOC_CON7 */ 326ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 327ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 328ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 329ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 330ba289af8SRoger Chen #define RK3366_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 331ba289af8SRoger Chen #define RK3366_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 332ba289af8SRoger Chen 333ba289af8SRoger Chen static void rk3366_set_to_rgmii(struct rk_priv_data *bsp_priv, 334ba289af8SRoger Chen int tx_delay, int rx_delay) 335ba289af8SRoger Chen { 336ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 337ba289af8SRoger Chen 338ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 339ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 340ba289af8SRoger Chen return; 341ba289af8SRoger Chen } 342ba289af8SRoger Chen 343ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 344ba289af8SRoger Chen RK3366_GMAC_PHY_INTF_SEL_RGMII | 345ba289af8SRoger Chen RK3366_GMAC_RMII_MODE_CLR); 346ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON7, 347ba289af8SRoger Chen RK3366_GMAC_RXCLK_DLY_ENABLE | 348ba289af8SRoger Chen RK3366_GMAC_TXCLK_DLY_ENABLE | 349ba289af8SRoger Chen RK3366_GMAC_CLK_RX_DL_CFG(rx_delay) | 350ba289af8SRoger Chen RK3366_GMAC_CLK_TX_DL_CFG(tx_delay)); 351ba289af8SRoger Chen } 352ba289af8SRoger Chen 353ba289af8SRoger Chen static void rk3366_set_to_rmii(struct rk_priv_data *bsp_priv) 354ba289af8SRoger Chen { 355ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 356ba289af8SRoger Chen 357ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 358ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 359ba289af8SRoger Chen return; 360ba289af8SRoger Chen } 361ba289af8SRoger Chen 362ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 363ba289af8SRoger Chen RK3366_GMAC_PHY_INTF_SEL_RMII | RK3366_GMAC_RMII_MODE); 364ba289af8SRoger Chen } 365ba289af8SRoger Chen 366ba289af8SRoger Chen static void rk3366_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 367ba289af8SRoger Chen { 368ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 369ba289af8SRoger Chen 370ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 371ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 372ba289af8SRoger Chen return; 373ba289af8SRoger Chen } 374ba289af8SRoger Chen 375ba289af8SRoger Chen if (speed == 10) 376ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 377ba289af8SRoger Chen RK3366_GMAC_CLK_2_5M); 378ba289af8SRoger Chen else if (speed == 100) 379ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 380ba289af8SRoger Chen RK3366_GMAC_CLK_25M); 381ba289af8SRoger Chen else if (speed == 1000) 382ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 383ba289af8SRoger Chen RK3366_GMAC_CLK_125M); 384ba289af8SRoger Chen else 385ba289af8SRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 386ba289af8SRoger Chen } 387ba289af8SRoger Chen 388ba289af8SRoger Chen static void rk3366_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 389ba289af8SRoger Chen { 390ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 391ba289af8SRoger Chen 392ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 393ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 394ba289af8SRoger Chen return; 395ba289af8SRoger Chen } 396ba289af8SRoger Chen 397ba289af8SRoger Chen if (speed == 10) { 398ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 399ba289af8SRoger Chen RK3366_GMAC_RMII_CLK_2_5M | 400ba289af8SRoger Chen RK3366_GMAC_SPEED_10M); 401ba289af8SRoger Chen } else if (speed == 100) { 402ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 403ba289af8SRoger Chen RK3366_GMAC_RMII_CLK_25M | 404ba289af8SRoger Chen RK3366_GMAC_SPEED_100M); 405ba289af8SRoger Chen } else { 406ba289af8SRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 407ba289af8SRoger Chen } 408ba289af8SRoger Chen } 409ba289af8SRoger Chen 410ba289af8SRoger Chen static const struct rk_gmac_ops rk3366_ops = { 411ba289af8SRoger Chen .set_to_rgmii = rk3366_set_to_rgmii, 412ba289af8SRoger Chen .set_to_rmii = rk3366_set_to_rmii, 413ba289af8SRoger Chen .set_rgmii_speed = rk3366_set_rgmii_speed, 414ba289af8SRoger Chen .set_rmii_speed = rk3366_set_rmii_speed, 415ba289af8SRoger Chen }; 416ba289af8SRoger Chen 417df558854SHeiko Stübner #define RK3368_GRF_SOC_CON15 0x043c 418df558854SHeiko Stübner #define RK3368_GRF_SOC_CON16 0x0440 419df558854SHeiko Stübner 420df558854SHeiko Stübner /* RK3368_GRF_SOC_CON15 */ 421df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 422df558854SHeiko Stübner GRF_CLR_BIT(11)) 423df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 424df558854SHeiko Stübner GRF_BIT(11)) 425df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL GRF_BIT(8) 426df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 427df558854SHeiko Stübner #define RK3368_GMAC_SPEED_10M GRF_CLR_BIT(7) 428df558854SHeiko Stübner #define RK3368_GMAC_SPEED_100M GRF_BIT(7) 429df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_25M GRF_BIT(3) 430df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 431df558854SHeiko Stübner #define RK3368_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 432df558854SHeiko Stübner #define RK3368_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 433df558854SHeiko Stübner #define RK3368_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 434df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE GRF_BIT(6) 435df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 436df558854SHeiko Stübner 437df558854SHeiko Stübner /* RK3368_GRF_SOC_CON16 */ 438df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 439df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 440df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 441df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 442df558854SHeiko Stübner #define RK3368_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 443df558854SHeiko Stübner #define RK3368_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 444df558854SHeiko Stübner 445df558854SHeiko Stübner static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv, 446df558854SHeiko Stübner int tx_delay, int rx_delay) 447df558854SHeiko Stübner { 448df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 449df558854SHeiko Stübner 450df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 451df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 452df558854SHeiko Stübner return; 453df558854SHeiko Stübner } 454df558854SHeiko Stübner 455df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 456df558854SHeiko Stübner RK3368_GMAC_PHY_INTF_SEL_RGMII | 457df558854SHeiko Stübner RK3368_GMAC_RMII_MODE_CLR); 458df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16, 459df558854SHeiko Stübner RK3368_GMAC_RXCLK_DLY_ENABLE | 460df558854SHeiko Stübner RK3368_GMAC_TXCLK_DLY_ENABLE | 461df558854SHeiko Stübner RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) | 462df558854SHeiko Stübner RK3368_GMAC_CLK_TX_DL_CFG(tx_delay)); 463df558854SHeiko Stübner } 464df558854SHeiko Stübner 465df558854SHeiko Stübner static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv) 466df558854SHeiko Stübner { 467df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 468df558854SHeiko Stübner 469df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 470df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 471df558854SHeiko Stübner return; 472df558854SHeiko Stübner } 473df558854SHeiko Stübner 474df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 475df558854SHeiko Stübner RK3368_GMAC_PHY_INTF_SEL_RMII | RK3368_GMAC_RMII_MODE); 476df558854SHeiko Stübner } 477df558854SHeiko Stübner 478df558854SHeiko Stübner static void rk3368_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 479df558854SHeiko Stübner { 480df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 481df558854SHeiko Stübner 482df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 483df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 484df558854SHeiko Stübner return; 485df558854SHeiko Stübner } 486df558854SHeiko Stübner 487df558854SHeiko Stübner if (speed == 10) 488df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 489df558854SHeiko Stübner RK3368_GMAC_CLK_2_5M); 490df558854SHeiko Stübner else if (speed == 100) 491df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 492df558854SHeiko Stübner RK3368_GMAC_CLK_25M); 493df558854SHeiko Stübner else if (speed == 1000) 494df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 495df558854SHeiko Stübner RK3368_GMAC_CLK_125M); 496df558854SHeiko Stübner else 497df558854SHeiko Stübner dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 498df558854SHeiko Stübner } 499df558854SHeiko Stübner 500df558854SHeiko Stübner static void rk3368_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 501df558854SHeiko Stübner { 502df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 503df558854SHeiko Stübner 504df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 505df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 506df558854SHeiko Stübner return; 507df558854SHeiko Stübner } 508df558854SHeiko Stübner 509df558854SHeiko Stübner if (speed == 10) { 510df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 511df558854SHeiko Stübner RK3368_GMAC_RMII_CLK_2_5M | 512df558854SHeiko Stübner RK3368_GMAC_SPEED_10M); 513df558854SHeiko Stübner } else if (speed == 100) { 514df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 515df558854SHeiko Stübner RK3368_GMAC_RMII_CLK_25M | 516df558854SHeiko Stübner RK3368_GMAC_SPEED_100M); 517df558854SHeiko Stübner } else { 518df558854SHeiko Stübner dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 519df558854SHeiko Stübner } 520df558854SHeiko Stübner } 521df558854SHeiko Stübner 52292c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3368_ops = { 523df558854SHeiko Stübner .set_to_rgmii = rk3368_set_to_rgmii, 524df558854SHeiko Stübner .set_to_rmii = rk3368_set_to_rmii, 525df558854SHeiko Stübner .set_rgmii_speed = rk3368_set_rgmii_speed, 526df558854SHeiko Stübner .set_rmii_speed = rk3368_set_rmii_speed, 527df558854SHeiko Stübner }; 528df558854SHeiko Stübner 529ba289af8SRoger Chen #define RK3399_GRF_SOC_CON5 0xc214 530ba289af8SRoger Chen #define RK3399_GRF_SOC_CON6 0xc218 531ba289af8SRoger Chen 532ba289af8SRoger Chen /* RK3399_GRF_SOC_CON5 */ 533ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 534ba289af8SRoger Chen GRF_CLR_BIT(11)) 535ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 536ba289af8SRoger Chen GRF_BIT(11)) 537ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL GRF_BIT(8) 538ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 539ba289af8SRoger Chen #define RK3399_GMAC_SPEED_10M GRF_CLR_BIT(7) 540ba289af8SRoger Chen #define RK3399_GMAC_SPEED_100M GRF_BIT(7) 541ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_25M GRF_BIT(3) 542ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 543ba289af8SRoger Chen #define RK3399_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 544ba289af8SRoger Chen #define RK3399_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 545ba289af8SRoger Chen #define RK3399_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 546ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE GRF_BIT(6) 547ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 548ba289af8SRoger Chen 549ba289af8SRoger Chen /* RK3399_GRF_SOC_CON6 */ 550ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 551ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 552ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 553ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 554ba289af8SRoger Chen #define RK3399_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 555ba289af8SRoger Chen #define RK3399_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 556ba289af8SRoger Chen 557ba289af8SRoger Chen static void rk3399_set_to_rgmii(struct rk_priv_data *bsp_priv, 558ba289af8SRoger Chen int tx_delay, int rx_delay) 559ba289af8SRoger Chen { 560ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 561ba289af8SRoger Chen 562ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 563ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 564ba289af8SRoger Chen return; 565ba289af8SRoger Chen } 566ba289af8SRoger Chen 567ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 568ba289af8SRoger Chen RK3399_GMAC_PHY_INTF_SEL_RGMII | 569ba289af8SRoger Chen RK3399_GMAC_RMII_MODE_CLR); 570ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON6, 571ba289af8SRoger Chen RK3399_GMAC_RXCLK_DLY_ENABLE | 572ba289af8SRoger Chen RK3399_GMAC_TXCLK_DLY_ENABLE | 573ba289af8SRoger Chen RK3399_GMAC_CLK_RX_DL_CFG(rx_delay) | 574ba289af8SRoger Chen RK3399_GMAC_CLK_TX_DL_CFG(tx_delay)); 575ba289af8SRoger Chen } 576ba289af8SRoger Chen 577ba289af8SRoger Chen static void rk3399_set_to_rmii(struct rk_priv_data *bsp_priv) 578ba289af8SRoger Chen { 579ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 580ba289af8SRoger Chen 581ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 582ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 583ba289af8SRoger Chen return; 584ba289af8SRoger Chen } 585ba289af8SRoger Chen 586ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 587ba289af8SRoger Chen RK3399_GMAC_PHY_INTF_SEL_RMII | RK3399_GMAC_RMII_MODE); 588ba289af8SRoger Chen } 589ba289af8SRoger Chen 590ba289af8SRoger Chen static void rk3399_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 591ba289af8SRoger Chen { 592ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 593ba289af8SRoger Chen 594ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 595ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 596ba289af8SRoger Chen return; 597ba289af8SRoger Chen } 598ba289af8SRoger Chen 599ba289af8SRoger Chen if (speed == 10) 600ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 601ba289af8SRoger Chen RK3399_GMAC_CLK_2_5M); 602ba289af8SRoger Chen else if (speed == 100) 603ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 604ba289af8SRoger Chen RK3399_GMAC_CLK_25M); 605ba289af8SRoger Chen else if (speed == 1000) 606ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 607ba289af8SRoger Chen RK3399_GMAC_CLK_125M); 608ba289af8SRoger Chen else 609ba289af8SRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 610ba289af8SRoger Chen } 611ba289af8SRoger Chen 612ba289af8SRoger Chen static void rk3399_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 613ba289af8SRoger Chen { 614ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 615ba289af8SRoger Chen 616ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 617ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 618ba289af8SRoger Chen return; 619ba289af8SRoger Chen } 620ba289af8SRoger Chen 621ba289af8SRoger Chen if (speed == 10) { 622ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 623ba289af8SRoger Chen RK3399_GMAC_RMII_CLK_2_5M | 624ba289af8SRoger Chen RK3399_GMAC_SPEED_10M); 625ba289af8SRoger Chen } else if (speed == 100) { 626ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 627ba289af8SRoger Chen RK3399_GMAC_RMII_CLK_25M | 628ba289af8SRoger Chen RK3399_GMAC_SPEED_100M); 629ba289af8SRoger Chen } else { 630ba289af8SRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 631ba289af8SRoger Chen } 632ba289af8SRoger Chen } 633ba289af8SRoger Chen 634ba289af8SRoger Chen static const struct rk_gmac_ops rk3399_ops = { 635ba289af8SRoger Chen .set_to_rgmii = rk3399_set_to_rgmii, 636ba289af8SRoger Chen .set_to_rmii = rk3399_set_to_rmii, 637ba289af8SRoger Chen .set_rgmii_speed = rk3399_set_rgmii_speed, 638ba289af8SRoger Chen .set_rmii_speed = rk3399_set_rmii_speed, 639ba289af8SRoger Chen }; 640ba289af8SRoger Chen 6417ad269eaSRoger Chen static int gmac_clk_init(struct rk_priv_data *bsp_priv) 6427ad269eaSRoger Chen { 6437ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 6447ad269eaSRoger Chen 6457ad269eaSRoger Chen bsp_priv->clk_enabled = false; 6467ad269eaSRoger Chen 6477ad269eaSRoger Chen bsp_priv->mac_clk_rx = devm_clk_get(dev, "mac_clk_rx"); 6487ad269eaSRoger Chen if (IS_ERR(bsp_priv->mac_clk_rx)) 649d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 650d42202dcSRomain Perier "mac_clk_rx"); 6517ad269eaSRoger Chen 6527ad269eaSRoger Chen bsp_priv->mac_clk_tx = devm_clk_get(dev, "mac_clk_tx"); 6537ad269eaSRoger Chen if (IS_ERR(bsp_priv->mac_clk_tx)) 654d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 655d42202dcSRomain Perier "mac_clk_tx"); 6567ad269eaSRoger Chen 6577ad269eaSRoger Chen bsp_priv->aclk_mac = devm_clk_get(dev, "aclk_mac"); 6587ad269eaSRoger Chen if (IS_ERR(bsp_priv->aclk_mac)) 659d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 660d42202dcSRomain Perier "aclk_mac"); 6617ad269eaSRoger Chen 6627ad269eaSRoger Chen bsp_priv->pclk_mac = devm_clk_get(dev, "pclk_mac"); 6637ad269eaSRoger Chen if (IS_ERR(bsp_priv->pclk_mac)) 664d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 665d42202dcSRomain Perier "pclk_mac"); 6667ad269eaSRoger Chen 6677ad269eaSRoger Chen bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth"); 6687ad269eaSRoger Chen if (IS_ERR(bsp_priv->clk_mac)) 669d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 670d42202dcSRomain Perier "stmmaceth"); 6717ad269eaSRoger Chen 6727ad269eaSRoger Chen if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) { 6737ad269eaSRoger Chen bsp_priv->clk_mac_ref = devm_clk_get(dev, "clk_mac_ref"); 6747ad269eaSRoger Chen if (IS_ERR(bsp_priv->clk_mac_ref)) 675d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 676d42202dcSRomain Perier "clk_mac_ref"); 6777ad269eaSRoger Chen 6787ad269eaSRoger Chen if (!bsp_priv->clock_input) { 6797ad269eaSRoger Chen bsp_priv->clk_mac_refout = 6807ad269eaSRoger Chen devm_clk_get(dev, "clk_mac_refout"); 6817ad269eaSRoger Chen if (IS_ERR(bsp_priv->clk_mac_refout)) 682d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 683d42202dcSRomain Perier "clk_mac_refout"); 6847ad269eaSRoger Chen } 6857ad269eaSRoger Chen } 6867ad269eaSRoger Chen 6877ad269eaSRoger Chen if (bsp_priv->clock_input) { 688d42202dcSRomain Perier dev_info(dev, "clock input from PHY\n"); 6897ad269eaSRoger Chen } else { 6907ad269eaSRoger Chen if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) 691c48fa33cSHeiko Stübner clk_set_rate(bsp_priv->clk_mac, 50000000); 6927ad269eaSRoger Chen } 6937ad269eaSRoger Chen 6947ad269eaSRoger Chen return 0; 6957ad269eaSRoger Chen } 6967ad269eaSRoger Chen 6977ad269eaSRoger Chen static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable) 6987ad269eaSRoger Chen { 699428ad1bcSLABBE Corentin int phy_iface = bsp_priv->phy_iface; 7007ad269eaSRoger Chen 7017ad269eaSRoger Chen if (enable) { 7027ad269eaSRoger Chen if (!bsp_priv->clk_enabled) { 7037ad269eaSRoger Chen if (phy_iface == PHY_INTERFACE_MODE_RMII) { 7047ad269eaSRoger Chen if (!IS_ERR(bsp_priv->mac_clk_rx)) 7057ad269eaSRoger Chen clk_prepare_enable( 7067ad269eaSRoger Chen bsp_priv->mac_clk_rx); 7077ad269eaSRoger Chen 7087ad269eaSRoger Chen if (!IS_ERR(bsp_priv->clk_mac_ref)) 7097ad269eaSRoger Chen clk_prepare_enable( 7107ad269eaSRoger Chen bsp_priv->clk_mac_ref); 7117ad269eaSRoger Chen 7127ad269eaSRoger Chen if (!IS_ERR(bsp_priv->clk_mac_refout)) 7137ad269eaSRoger Chen clk_prepare_enable( 7147ad269eaSRoger Chen bsp_priv->clk_mac_refout); 7157ad269eaSRoger Chen } 7167ad269eaSRoger Chen 7177ad269eaSRoger Chen if (!IS_ERR(bsp_priv->aclk_mac)) 7187ad269eaSRoger Chen clk_prepare_enable(bsp_priv->aclk_mac); 7197ad269eaSRoger Chen 7207ad269eaSRoger Chen if (!IS_ERR(bsp_priv->pclk_mac)) 7217ad269eaSRoger Chen clk_prepare_enable(bsp_priv->pclk_mac); 7227ad269eaSRoger Chen 7237ad269eaSRoger Chen if (!IS_ERR(bsp_priv->mac_clk_tx)) 7247ad269eaSRoger Chen clk_prepare_enable(bsp_priv->mac_clk_tx); 7257ad269eaSRoger Chen 7267ad269eaSRoger Chen /** 7277ad269eaSRoger Chen * if (!IS_ERR(bsp_priv->clk_mac)) 7287ad269eaSRoger Chen * clk_prepare_enable(bsp_priv->clk_mac); 7297ad269eaSRoger Chen */ 7307ad269eaSRoger Chen mdelay(5); 7317ad269eaSRoger Chen bsp_priv->clk_enabled = true; 7327ad269eaSRoger Chen } 7337ad269eaSRoger Chen } else { 7347ad269eaSRoger Chen if (bsp_priv->clk_enabled) { 7357ad269eaSRoger Chen if (phy_iface == PHY_INTERFACE_MODE_RMII) { 7367ad269eaSRoger Chen if (!IS_ERR(bsp_priv->mac_clk_rx)) 7377ad269eaSRoger Chen clk_disable_unprepare( 7387ad269eaSRoger Chen bsp_priv->mac_clk_rx); 7397ad269eaSRoger Chen 7407ad269eaSRoger Chen if (!IS_ERR(bsp_priv->clk_mac_ref)) 7417ad269eaSRoger Chen clk_disable_unprepare( 7427ad269eaSRoger Chen bsp_priv->clk_mac_ref); 7437ad269eaSRoger Chen 7447ad269eaSRoger Chen if (!IS_ERR(bsp_priv->clk_mac_refout)) 7457ad269eaSRoger Chen clk_disable_unprepare( 7467ad269eaSRoger Chen bsp_priv->clk_mac_refout); 7477ad269eaSRoger Chen } 7487ad269eaSRoger Chen 7497ad269eaSRoger Chen if (!IS_ERR(bsp_priv->aclk_mac)) 7507ad269eaSRoger Chen clk_disable_unprepare(bsp_priv->aclk_mac); 7517ad269eaSRoger Chen 7527ad269eaSRoger Chen if (!IS_ERR(bsp_priv->pclk_mac)) 7537ad269eaSRoger Chen clk_disable_unprepare(bsp_priv->pclk_mac); 7547ad269eaSRoger Chen 7557ad269eaSRoger Chen if (!IS_ERR(bsp_priv->mac_clk_tx)) 7567ad269eaSRoger Chen clk_disable_unprepare(bsp_priv->mac_clk_tx); 7577ad269eaSRoger Chen /** 7587ad269eaSRoger Chen * if (!IS_ERR(bsp_priv->clk_mac)) 7597ad269eaSRoger Chen * clk_disable_unprepare(bsp_priv->clk_mac); 7607ad269eaSRoger Chen */ 7617ad269eaSRoger Chen bsp_priv->clk_enabled = false; 7627ad269eaSRoger Chen } 7637ad269eaSRoger Chen } 7647ad269eaSRoger Chen 7657ad269eaSRoger Chen return 0; 7667ad269eaSRoger Chen } 7677ad269eaSRoger Chen 7687ad269eaSRoger Chen static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable) 7697ad269eaSRoger Chen { 7702e12f536SRomain Perier struct regulator *ldo = bsp_priv->regulator; 7717ad269eaSRoger Chen int ret; 7727ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 7737ad269eaSRoger Chen 7742e12f536SRomain Perier if (!ldo) { 775d42202dcSRomain Perier dev_err(dev, "no regulator found\n"); 7767ad269eaSRoger Chen return -1; 7777ad269eaSRoger Chen } 7787ad269eaSRoger Chen 7797ad269eaSRoger Chen if (enable) { 7807ad269eaSRoger Chen ret = regulator_enable(ldo); 7812e12f536SRomain Perier if (ret) 782d42202dcSRomain Perier dev_err(dev, "fail to enable phy-supply\n"); 7837ad269eaSRoger Chen } else { 7847ad269eaSRoger Chen ret = regulator_disable(ldo); 7852e12f536SRomain Perier if (ret) 786d42202dcSRomain Perier dev_err(dev, "fail to disable phy-supply\n"); 7877ad269eaSRoger Chen } 7887ad269eaSRoger Chen 7897ad269eaSRoger Chen return 0; 7907ad269eaSRoger Chen } 7917ad269eaSRoger Chen 7920fb98db1SHeiko Stübner static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev, 79392c2588fSJoachim Eastwood const struct rk_gmac_ops *ops) 7947ad269eaSRoger Chen { 7957ad269eaSRoger Chen struct rk_priv_data *bsp_priv; 7967ad269eaSRoger Chen struct device *dev = &pdev->dev; 7977ad269eaSRoger Chen int ret; 7987ad269eaSRoger Chen const char *strings = NULL; 7997ad269eaSRoger Chen int value; 8007ad269eaSRoger Chen 8017ad269eaSRoger Chen bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL); 8027ad269eaSRoger Chen if (!bsp_priv) 8037ad269eaSRoger Chen return ERR_PTR(-ENOMEM); 8047ad269eaSRoger Chen 8057ad269eaSRoger Chen bsp_priv->phy_iface = of_get_phy_mode(dev->of_node); 8060fb98db1SHeiko Stübner bsp_priv->ops = ops; 8077ad269eaSRoger Chen 8082e12f536SRomain Perier bsp_priv->regulator = devm_regulator_get_optional(dev, "phy"); 8092e12f536SRomain Perier if (IS_ERR(bsp_priv->regulator)) { 8102e12f536SRomain Perier if (PTR_ERR(bsp_priv->regulator) == -EPROBE_DEFER) { 8112e12f536SRomain Perier dev_err(dev, "phy regulator is not available yet, deferred probing\n"); 8122e12f536SRomain Perier return ERR_PTR(-EPROBE_DEFER); 8132e12f536SRomain Perier } 8142e12f536SRomain Perier dev_err(dev, "no regulator found\n"); 8152e12f536SRomain Perier bsp_priv->regulator = NULL; 8167ad269eaSRoger Chen } 8177ad269eaSRoger Chen 8187ad269eaSRoger Chen ret = of_property_read_string(dev->of_node, "clock_in_out", &strings); 8197ad269eaSRoger Chen if (ret) { 820d42202dcSRomain Perier dev_err(dev, "Can not read property: clock_in_out.\n"); 8217ad269eaSRoger Chen bsp_priv->clock_input = true; 8227ad269eaSRoger Chen } else { 823d42202dcSRomain Perier dev_info(dev, "clock input or output? (%s).\n", 824d42202dcSRomain Perier strings); 8257ad269eaSRoger Chen if (!strcmp(strings, "input")) 8267ad269eaSRoger Chen bsp_priv->clock_input = true; 8277ad269eaSRoger Chen else 8287ad269eaSRoger Chen bsp_priv->clock_input = false; 8297ad269eaSRoger Chen } 8307ad269eaSRoger Chen 8317ad269eaSRoger Chen ret = of_property_read_u32(dev->of_node, "tx_delay", &value); 8327ad269eaSRoger Chen if (ret) { 8337ad269eaSRoger Chen bsp_priv->tx_delay = 0x30; 834d42202dcSRomain Perier dev_err(dev, "Can not read property: tx_delay."); 835d42202dcSRomain Perier dev_err(dev, "set tx_delay to 0x%x\n", 836d42202dcSRomain Perier bsp_priv->tx_delay); 8377ad269eaSRoger Chen } else { 838d42202dcSRomain Perier dev_info(dev, "TX delay(0x%x).\n", value); 8397ad269eaSRoger Chen bsp_priv->tx_delay = value; 8407ad269eaSRoger Chen } 8417ad269eaSRoger Chen 8427ad269eaSRoger Chen ret = of_property_read_u32(dev->of_node, "rx_delay", &value); 8437ad269eaSRoger Chen if (ret) { 8447ad269eaSRoger Chen bsp_priv->rx_delay = 0x10; 845d42202dcSRomain Perier dev_err(dev, "Can not read property: rx_delay."); 846d42202dcSRomain Perier dev_err(dev, "set rx_delay to 0x%x\n", 847d42202dcSRomain Perier bsp_priv->rx_delay); 8487ad269eaSRoger Chen } else { 849d42202dcSRomain Perier dev_info(dev, "RX delay(0x%x).\n", value); 8507ad269eaSRoger Chen bsp_priv->rx_delay = value; 8517ad269eaSRoger Chen } 8527ad269eaSRoger Chen 8537ad269eaSRoger Chen bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node, 8547ad269eaSRoger Chen "rockchip,grf"); 8557ad269eaSRoger Chen bsp_priv->pdev = pdev; 8567ad269eaSRoger Chen 85745383f52SRoger Chen gmac_clk_init(bsp_priv); 85845383f52SRoger Chen 85945383f52SRoger Chen return bsp_priv; 86045383f52SRoger Chen } 86145383f52SRoger Chen 86245383f52SRoger Chen static int rk_gmac_powerup(struct rk_priv_data *bsp_priv) 86345383f52SRoger Chen { 86445383f52SRoger Chen int ret; 86545383f52SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 86645383f52SRoger Chen 8677ad269eaSRoger Chen /*rmii or rgmii*/ 8687ad269eaSRoger Chen if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RGMII) { 869d42202dcSRomain Perier dev_info(dev, "init for RGMII\n"); 8700fb98db1SHeiko Stübner bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 8710fb98db1SHeiko Stübner bsp_priv->rx_delay); 8727ad269eaSRoger Chen } else if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) { 873d42202dcSRomain Perier dev_info(dev, "init for RMII\n"); 8740fb98db1SHeiko Stübner bsp_priv->ops->set_to_rmii(bsp_priv); 8757ad269eaSRoger Chen } else { 876d42202dcSRomain Perier dev_err(dev, "NO interface defined!\n"); 8777ad269eaSRoger Chen } 8787ad269eaSRoger Chen 8797ad269eaSRoger Chen ret = phy_power_on(bsp_priv, true); 8807ad269eaSRoger Chen if (ret) 8817ad269eaSRoger Chen return ret; 8827ad269eaSRoger Chen 8837ad269eaSRoger Chen ret = gmac_clk_enable(bsp_priv, true); 8847ad269eaSRoger Chen if (ret) 8857ad269eaSRoger Chen return ret; 8867ad269eaSRoger Chen 8872c896fb0SDavid Wu pm_runtime_enable(dev); 8882c896fb0SDavid Wu pm_runtime_get_sync(dev); 8892c896fb0SDavid Wu 8907ad269eaSRoger Chen return 0; 8917ad269eaSRoger Chen } 8927ad269eaSRoger Chen 893229666c1SVincent Palatin static void rk_gmac_powerdown(struct rk_priv_data *gmac) 8947ad269eaSRoger Chen { 8952c896fb0SDavid Wu struct device *dev = &gmac->pdev->dev; 8962c896fb0SDavid Wu 8972c896fb0SDavid Wu pm_runtime_put_sync(dev); 8982c896fb0SDavid Wu pm_runtime_disable(dev); 8992c896fb0SDavid Wu 9007ad269eaSRoger Chen phy_power_on(gmac, false); 9017ad269eaSRoger Chen gmac_clk_enable(gmac, false); 9027ad269eaSRoger Chen } 9037ad269eaSRoger Chen 9047ad269eaSRoger Chen static void rk_fix_speed(void *priv, unsigned int speed) 9057ad269eaSRoger Chen { 9067ad269eaSRoger Chen struct rk_priv_data *bsp_priv = priv; 9077ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 9087ad269eaSRoger Chen 9097ad269eaSRoger Chen if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RGMII) 9100fb98db1SHeiko Stübner bsp_priv->ops->set_rgmii_speed(bsp_priv, speed); 9117ad269eaSRoger Chen else if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) 9120fb98db1SHeiko Stübner bsp_priv->ops->set_rmii_speed(bsp_priv, speed); 9137ad269eaSRoger Chen else 9147ad269eaSRoger Chen dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface); 9157ad269eaSRoger Chen } 9167ad269eaSRoger Chen 91727ffefd2SJoachim Eastwood static int rk_gmac_probe(struct platform_device *pdev) 91827ffefd2SJoachim Eastwood { 91927ffefd2SJoachim Eastwood struct plat_stmmacenet_data *plat_dat; 92027ffefd2SJoachim Eastwood struct stmmac_resources stmmac_res; 921f529f182SJoachim Eastwood const struct rk_gmac_ops *data; 92227ffefd2SJoachim Eastwood int ret; 92327ffefd2SJoachim Eastwood 924149adeddSJoachim Eastwood data = of_device_get_match_data(&pdev->dev); 925149adeddSJoachim Eastwood if (!data) { 926149adeddSJoachim Eastwood dev_err(&pdev->dev, "no of match data provided\n"); 927149adeddSJoachim Eastwood return -EINVAL; 928149adeddSJoachim Eastwood } 929149adeddSJoachim Eastwood 93027ffefd2SJoachim Eastwood ret = stmmac_get_platform_resources(pdev, &stmmac_res); 93127ffefd2SJoachim Eastwood if (ret) 93227ffefd2SJoachim Eastwood return ret; 93327ffefd2SJoachim Eastwood 93427ffefd2SJoachim Eastwood plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac); 93527ffefd2SJoachim Eastwood if (IS_ERR(plat_dat)) 93627ffefd2SJoachim Eastwood return PTR_ERR(plat_dat); 93727ffefd2SJoachim Eastwood 93827ffefd2SJoachim Eastwood plat_dat->has_gmac = true; 93927ffefd2SJoachim Eastwood plat_dat->fix_mac_speed = rk_fix_speed; 94027ffefd2SJoachim Eastwood 941f529f182SJoachim Eastwood plat_dat->bsp_priv = rk_gmac_setup(pdev, data); 94227ffefd2SJoachim Eastwood if (IS_ERR(plat_dat->bsp_priv)) 94327ffefd2SJoachim Eastwood return PTR_ERR(plat_dat->bsp_priv); 94427ffefd2SJoachim Eastwood 945*07a5e769SJoachim Eastwood ret = rk_gmac_powerup(plat_dat->bsp_priv); 94627ffefd2SJoachim Eastwood if (ret) 94727ffefd2SJoachim Eastwood return ret; 94827ffefd2SJoachim Eastwood 94927ffefd2SJoachim Eastwood return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); 95027ffefd2SJoachim Eastwood } 95127ffefd2SJoachim Eastwood 9520de8c4c9SJoachim Eastwood static int rk_gmac_remove(struct platform_device *pdev) 9530de8c4c9SJoachim Eastwood { 9540de8c4c9SJoachim Eastwood struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(&pdev->dev); 9550de8c4c9SJoachim Eastwood int ret = stmmac_dvr_remove(&pdev->dev); 9560de8c4c9SJoachim Eastwood 9570de8c4c9SJoachim Eastwood rk_gmac_powerdown(bsp_priv); 9580de8c4c9SJoachim Eastwood 9590de8c4c9SJoachim Eastwood return ret; 9600de8c4c9SJoachim Eastwood } 9610de8c4c9SJoachim Eastwood 9625619468aSJoachim Eastwood #ifdef CONFIG_PM_SLEEP 9635619468aSJoachim Eastwood static int rk_gmac_suspend(struct device *dev) 9645619468aSJoachim Eastwood { 9655619468aSJoachim Eastwood struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev); 9665619468aSJoachim Eastwood int ret = stmmac_suspend(dev); 9675619468aSJoachim Eastwood 9685619468aSJoachim Eastwood /* Keep the PHY up if we use Wake-on-Lan. */ 9695619468aSJoachim Eastwood if (!device_may_wakeup(dev)) { 9705619468aSJoachim Eastwood rk_gmac_powerdown(bsp_priv); 9715619468aSJoachim Eastwood bsp_priv->suspended = true; 9725619468aSJoachim Eastwood } 9735619468aSJoachim Eastwood 9745619468aSJoachim Eastwood return ret; 9755619468aSJoachim Eastwood } 9765619468aSJoachim Eastwood 9775619468aSJoachim Eastwood static int rk_gmac_resume(struct device *dev) 9785619468aSJoachim Eastwood { 9795619468aSJoachim Eastwood struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev); 9805619468aSJoachim Eastwood 9815619468aSJoachim Eastwood /* The PHY was up for Wake-on-Lan. */ 9825619468aSJoachim Eastwood if (bsp_priv->suspended) { 9835619468aSJoachim Eastwood rk_gmac_powerup(bsp_priv); 9845619468aSJoachim Eastwood bsp_priv->suspended = false; 9855619468aSJoachim Eastwood } 9865619468aSJoachim Eastwood 9875619468aSJoachim Eastwood return stmmac_resume(dev); 9885619468aSJoachim Eastwood } 9895619468aSJoachim Eastwood #endif /* CONFIG_PM_SLEEP */ 9905619468aSJoachim Eastwood 9915619468aSJoachim Eastwood static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume); 9925619468aSJoachim Eastwood 993e0fb4013SJoachim Eastwood static const struct of_device_id rk_gmac_dwmac_match[] = { 994e7ffd812SXing Zheng { .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops }, 995f529f182SJoachim Eastwood { .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops }, 996ba289af8SRoger Chen { .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops }, 997f529f182SJoachim Eastwood { .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops }, 998ba289af8SRoger Chen { .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops }, 999e0fb4013SJoachim Eastwood { } 1000e0fb4013SJoachim Eastwood }; 1001e0fb4013SJoachim Eastwood MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match); 1002e0fb4013SJoachim Eastwood 1003e0fb4013SJoachim Eastwood static struct platform_driver rk_gmac_dwmac_driver = { 100427ffefd2SJoachim Eastwood .probe = rk_gmac_probe, 10050de8c4c9SJoachim Eastwood .remove = rk_gmac_remove, 1006e0fb4013SJoachim Eastwood .driver = { 1007e0fb4013SJoachim Eastwood .name = "rk_gmac-dwmac", 10085619468aSJoachim Eastwood .pm = &rk_gmac_pm_ops, 1009e0fb4013SJoachim Eastwood .of_match_table = rk_gmac_dwmac_match, 1010e0fb4013SJoachim Eastwood }, 1011e0fb4013SJoachim Eastwood }; 1012e0fb4013SJoachim Eastwood module_platform_driver(rk_gmac_dwmac_driver); 1013e0fb4013SJoachim Eastwood 1014e0fb4013SJoachim Eastwood MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>"); 1015e0fb4013SJoachim Eastwood MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer"); 1016e0fb4013SJoachim Eastwood MODULE_LICENSE("GPL"); 1017