1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 27ad269eaSRoger Chen /** 3d0ea5cbdSJesse Brandeburg * DOC: dwmac-rk.c - Rockchip RK3288 DWMAC specific glue layer 47ad269eaSRoger Chen * 57ad269eaSRoger Chen * Copyright (C) 2014 Chen-Zhi (Roger Chen) 67ad269eaSRoger Chen * 77ad269eaSRoger Chen * Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com> 87ad269eaSRoger Chen */ 97ad269eaSRoger Chen 107ad269eaSRoger Chen #include <linux/stmmac.h> 117ad269eaSRoger Chen #include <linux/bitops.h> 127ad269eaSRoger Chen #include <linux/clk.h> 137ad269eaSRoger Chen #include <linux/phy.h> 147ad269eaSRoger Chen #include <linux/of_net.h> 157ad269eaSRoger Chen #include <linux/gpio.h> 16e0fb4013SJoachim Eastwood #include <linux/module.h> 177ad269eaSRoger Chen #include <linux/of_gpio.h> 187ad269eaSRoger Chen #include <linux/of_device.h> 19e0fb4013SJoachim Eastwood #include <linux/platform_device.h> 207ad269eaSRoger Chen #include <linux/regulator/consumer.h> 217ad269eaSRoger Chen #include <linux/delay.h> 227ad269eaSRoger Chen #include <linux/mfd/syscon.h> 237ad269eaSRoger Chen #include <linux/regmap.h> 24aec3f415SPunit Agrawal #include <linux/pm_runtime.h> 257ad269eaSRoger Chen 26e0fb4013SJoachim Eastwood #include "stmmac_platform.h" 27e0fb4013SJoachim Eastwood 280fb98db1SHeiko Stübner struct rk_priv_data; 290fb98db1SHeiko Stübner struct rk_gmac_ops { 300fb98db1SHeiko Stübner void (*set_to_rgmii)(struct rk_priv_data *bsp_priv, 310fb98db1SHeiko Stübner int tx_delay, int rx_delay); 320fb98db1SHeiko Stübner void (*set_to_rmii)(struct rk_priv_data *bsp_priv); 330fb98db1SHeiko Stübner void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed); 340fb98db1SHeiko Stübner void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed); 352f2b60a0SDavid Wu void (*set_clock_selection)(struct rk_priv_data *bsp_priv, bool input, 362f2b60a0SDavid Wu bool enable); 37fecd4d7eSDavid Wu void (*integrated_phy_powerup)(struct rk_priv_data *bsp_priv); 380546b224SJohn Keeping bool regs_valid; 393bb3d6b1SDavid Wu u32 regs[]; 400fb98db1SHeiko Stübner }; 410fb98db1SHeiko Stübner 427ad269eaSRoger Chen struct rk_priv_data { 437ad269eaSRoger Chen struct platform_device *pdev; 440c65b2b9SAndrew Lunn phy_interface_t phy_iface; 453bb3d6b1SDavid Wu int id; 462e12f536SRomain Perier struct regulator *regulator; 47229666c1SVincent Palatin bool suspended; 4892c2588fSJoachim Eastwood const struct rk_gmac_ops *ops; 497ad269eaSRoger Chen 507ad269eaSRoger Chen bool clk_enabled; 517ad269eaSRoger Chen bool clock_input; 52fecd4d7eSDavid Wu bool integrated_phy; 537ad269eaSRoger Chen 547ad269eaSRoger Chen struct clk *clk_mac; 557ad269eaSRoger Chen struct clk *gmac_clkin; 567ad269eaSRoger Chen struct clk *mac_clk_rx; 577ad269eaSRoger Chen struct clk *mac_clk_tx; 587ad269eaSRoger Chen struct clk *clk_mac_ref; 597ad269eaSRoger Chen struct clk *clk_mac_refout; 6023c94d63SDavid Wu struct clk *clk_mac_speed; 617ad269eaSRoger Chen struct clk *aclk_mac; 627ad269eaSRoger Chen struct clk *pclk_mac; 63fecd4d7eSDavid Wu struct clk *clk_phy; 64fecd4d7eSDavid Wu 65fecd4d7eSDavid Wu struct reset_control *phy_reset; 667ad269eaSRoger Chen 677ad269eaSRoger Chen int tx_delay; 687ad269eaSRoger Chen int rx_delay; 697ad269eaSRoger Chen 707ad269eaSRoger Chen struct regmap *grf; 712f2b60a0SDavid Wu struct regmap *php_grf; 727ad269eaSRoger Chen }; 737ad269eaSRoger Chen 747ad269eaSRoger Chen #define HIWORD_UPDATE(val, mask, shift) \ 757ad269eaSRoger Chen ((val) << (shift) | (mask) << ((shift) + 16)) 767ad269eaSRoger Chen 777ad269eaSRoger Chen #define GRF_BIT(nr) (BIT(nr) | BIT(nr+16)) 787ad269eaSRoger Chen #define GRF_CLR_BIT(nr) (BIT(nr+16)) 797ad269eaSRoger Chen 80eaf70ad1SWadim Egorov #define DELAY_ENABLE(soc, tx, rx) \ 81eaf70ad1SWadim Egorov (((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \ 82eaf70ad1SWadim Egorov ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE)) 83eaf70ad1SWadim Egorov 8423c94d63SDavid Wu #define PX30_GRF_GMAC_CON1 0x0904 8523c94d63SDavid Wu 8623c94d63SDavid Wu /* PX30_GRF_GMAC_CON1 */ 8723c94d63SDavid Wu #define PX30_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \ 8823c94d63SDavid Wu GRF_BIT(6)) 8923c94d63SDavid Wu #define PX30_GMAC_SPEED_10M GRF_CLR_BIT(2) 9023c94d63SDavid Wu #define PX30_GMAC_SPEED_100M GRF_BIT(2) 9123c94d63SDavid Wu 9223c94d63SDavid Wu static void px30_set_to_rmii(struct rk_priv_data *bsp_priv) 9323c94d63SDavid Wu { 9423c94d63SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 9523c94d63SDavid Wu 9623c94d63SDavid Wu if (IS_ERR(bsp_priv->grf)) { 9723c94d63SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 9823c94d63SDavid Wu return; 9923c94d63SDavid Wu } 10023c94d63SDavid Wu 10123c94d63SDavid Wu regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1, 10223c94d63SDavid Wu PX30_GMAC_PHY_INTF_SEL_RMII); 10323c94d63SDavid Wu } 10423c94d63SDavid Wu 10523c94d63SDavid Wu static void px30_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 10623c94d63SDavid Wu { 10723c94d63SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 10823c94d63SDavid Wu int ret; 10923c94d63SDavid Wu 11023c94d63SDavid Wu if (IS_ERR(bsp_priv->clk_mac_speed)) { 11123c94d63SDavid Wu dev_err(dev, "%s: Missing clk_mac_speed clock\n", __func__); 11223c94d63SDavid Wu return; 11323c94d63SDavid Wu } 11423c94d63SDavid Wu 11523c94d63SDavid Wu if (speed == 10) { 11623c94d63SDavid Wu regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1, 11723c94d63SDavid Wu PX30_GMAC_SPEED_10M); 11823c94d63SDavid Wu 11923c94d63SDavid Wu ret = clk_set_rate(bsp_priv->clk_mac_speed, 2500000); 12023c94d63SDavid Wu if (ret) 12123c94d63SDavid Wu dev_err(dev, "%s: set clk_mac_speed rate 2500000 failed: %d\n", 12223c94d63SDavid Wu __func__, ret); 12323c94d63SDavid Wu } else if (speed == 100) { 12423c94d63SDavid Wu regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1, 12523c94d63SDavid Wu PX30_GMAC_SPEED_100M); 12623c94d63SDavid Wu 12723c94d63SDavid Wu ret = clk_set_rate(bsp_priv->clk_mac_speed, 25000000); 12823c94d63SDavid Wu if (ret) 12923c94d63SDavid Wu dev_err(dev, "%s: set clk_mac_speed rate 25000000 failed: %d\n", 13023c94d63SDavid Wu __func__, ret); 13123c94d63SDavid Wu 13223c94d63SDavid Wu } else { 13323c94d63SDavid Wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 13423c94d63SDavid Wu } 13523c94d63SDavid Wu } 13623c94d63SDavid Wu 13723c94d63SDavid Wu static const struct rk_gmac_ops px30_ops = { 13823c94d63SDavid Wu .set_to_rmii = px30_set_to_rmii, 13923c94d63SDavid Wu .set_rmii_speed = px30_set_rmii_speed, 14023c94d63SDavid Wu }; 14123c94d63SDavid Wu 14205946876SDavid Wu #define RK3128_GRF_MAC_CON0 0x0168 14305946876SDavid Wu #define RK3128_GRF_MAC_CON1 0x016c 14405946876SDavid Wu 14505946876SDavid Wu /* RK3128_GRF_MAC_CON0 */ 14605946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_ENABLE GRF_BIT(14) 14705946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14) 14805946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 14905946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 15005946876SDavid Wu #define RK3128_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 15105946876SDavid Wu #define RK3128_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 15205946876SDavid Wu 15305946876SDavid Wu /* RK3128_GRF_MAC_CON1 */ 15405946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RGMII \ 15505946876SDavid Wu (GRF_BIT(6) | GRF_CLR_BIT(7) | GRF_CLR_BIT(8)) 15605946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RMII \ 15705946876SDavid Wu (GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | GRF_BIT(8)) 15805946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL GRF_BIT(9) 15905946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(9) 16005946876SDavid Wu #define RK3128_GMAC_SPEED_10M GRF_CLR_BIT(10) 16105946876SDavid Wu #define RK3128_GMAC_SPEED_100M GRF_BIT(10) 16205946876SDavid Wu #define RK3128_GMAC_RMII_CLK_25M GRF_BIT(11) 16305946876SDavid Wu #define RK3128_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(11) 16405946876SDavid Wu #define RK3128_GMAC_CLK_125M (GRF_CLR_BIT(12) | GRF_CLR_BIT(13)) 16505946876SDavid Wu #define RK3128_GMAC_CLK_25M (GRF_BIT(12) | GRF_BIT(13)) 16605946876SDavid Wu #define RK3128_GMAC_CLK_2_5M (GRF_CLR_BIT(12) | GRF_BIT(13)) 16705946876SDavid Wu #define RK3128_GMAC_RMII_MODE GRF_BIT(14) 16805946876SDavid Wu #define RK3128_GMAC_RMII_MODE_CLR GRF_CLR_BIT(14) 16905946876SDavid Wu 17005946876SDavid Wu static void rk3128_set_to_rgmii(struct rk_priv_data *bsp_priv, 17105946876SDavid Wu int tx_delay, int rx_delay) 17205946876SDavid Wu { 17305946876SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 17405946876SDavid Wu 17505946876SDavid Wu if (IS_ERR(bsp_priv->grf)) { 17605946876SDavid Wu dev_err(dev, "Missing rockchip,grf property\n"); 17705946876SDavid Wu return; 17805946876SDavid Wu } 17905946876SDavid Wu 18005946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 18105946876SDavid Wu RK3128_GMAC_PHY_INTF_SEL_RGMII | 18205946876SDavid Wu RK3128_GMAC_RMII_MODE_CLR); 18305946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON0, 18405946876SDavid Wu DELAY_ENABLE(RK3128, tx_delay, rx_delay) | 18505946876SDavid Wu RK3128_GMAC_CLK_RX_DL_CFG(rx_delay) | 18605946876SDavid Wu RK3128_GMAC_CLK_TX_DL_CFG(tx_delay)); 18705946876SDavid Wu } 18805946876SDavid Wu 18905946876SDavid Wu static void rk3128_set_to_rmii(struct rk_priv_data *bsp_priv) 19005946876SDavid Wu { 19105946876SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 19205946876SDavid Wu 19305946876SDavid Wu if (IS_ERR(bsp_priv->grf)) { 19405946876SDavid Wu dev_err(dev, "Missing rockchip,grf property\n"); 19505946876SDavid Wu return; 19605946876SDavid Wu } 19705946876SDavid Wu 19805946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 19905946876SDavid Wu RK3128_GMAC_PHY_INTF_SEL_RMII | RK3128_GMAC_RMII_MODE); 20005946876SDavid Wu } 20105946876SDavid Wu 20205946876SDavid Wu static void rk3128_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 20305946876SDavid Wu { 20405946876SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 20505946876SDavid Wu 20605946876SDavid Wu if (IS_ERR(bsp_priv->grf)) { 20705946876SDavid Wu dev_err(dev, "Missing rockchip,grf property\n"); 20805946876SDavid Wu return; 20905946876SDavid Wu } 21005946876SDavid Wu 21105946876SDavid Wu if (speed == 10) 21205946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 21305946876SDavid Wu RK3128_GMAC_CLK_2_5M); 21405946876SDavid Wu else if (speed == 100) 21505946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 21605946876SDavid Wu RK3128_GMAC_CLK_25M); 21705946876SDavid Wu else if (speed == 1000) 21805946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 21905946876SDavid Wu RK3128_GMAC_CLK_125M); 22005946876SDavid Wu else 22105946876SDavid Wu dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 22205946876SDavid Wu } 22305946876SDavid Wu 22405946876SDavid Wu static void rk3128_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 22505946876SDavid Wu { 22605946876SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 22705946876SDavid Wu 22805946876SDavid Wu if (IS_ERR(bsp_priv->grf)) { 22905946876SDavid Wu dev_err(dev, "Missing rockchip,grf property\n"); 23005946876SDavid Wu return; 23105946876SDavid Wu } 23205946876SDavid Wu 23305946876SDavid Wu if (speed == 10) { 23405946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 23505946876SDavid Wu RK3128_GMAC_RMII_CLK_2_5M | 23605946876SDavid Wu RK3128_GMAC_SPEED_10M); 23705946876SDavid Wu } else if (speed == 100) { 23805946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 23905946876SDavid Wu RK3128_GMAC_RMII_CLK_25M | 24005946876SDavid Wu RK3128_GMAC_SPEED_100M); 24105946876SDavid Wu } else { 24205946876SDavid Wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 24305946876SDavid Wu } 24405946876SDavid Wu } 24505946876SDavid Wu 24605946876SDavid Wu static const struct rk_gmac_ops rk3128_ops = { 24705946876SDavid Wu .set_to_rgmii = rk3128_set_to_rgmii, 24805946876SDavid Wu .set_to_rmii = rk3128_set_to_rmii, 24905946876SDavid Wu .set_rgmii_speed = rk3128_set_rgmii_speed, 25005946876SDavid Wu .set_rmii_speed = rk3128_set_rmii_speed, 25105946876SDavid Wu }; 25205946876SDavid Wu 253e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON0 0x0900 254e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON1 0x0904 255e7ffd812SXing Zheng 2566fa12c78SDavid Wu #define RK3228_GRF_CON_MUX 0x50 2576fa12c78SDavid Wu 258e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON0 */ 259e7ffd812SXing Zheng #define RK3228_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 260e7ffd812SXing Zheng #define RK3228_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 261e7ffd812SXing Zheng 262e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON1 */ 263e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RGMII \ 264e7ffd812SXing Zheng (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6)) 265e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RMII \ 266e7ffd812SXing Zheng (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6)) 267e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL GRF_BIT(3) 268e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 269e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_10M GRF_CLR_BIT(2) 270e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_100M GRF_BIT(2) 271e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_25M GRF_BIT(7) 272e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7) 273e7ffd812SXing Zheng #define RK3228_GMAC_CLK_125M (GRF_CLR_BIT(8) | GRF_CLR_BIT(9)) 274e7ffd812SXing Zheng #define RK3228_GMAC_CLK_25M (GRF_BIT(8) | GRF_BIT(9)) 275e7ffd812SXing Zheng #define RK3228_GMAC_CLK_2_5M (GRF_CLR_BIT(8) | GRF_BIT(9)) 276e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE GRF_BIT(10) 277e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE_CLR GRF_CLR_BIT(10) 278e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0) 279e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0) 280e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1) 281e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(1) 282e7ffd812SXing Zheng 2836fa12c78SDavid Wu /* RK3228_GRF_COM_MUX */ 2846fa12c78SDavid Wu #define RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY GRF_BIT(15) 2856fa12c78SDavid Wu 286e7ffd812SXing Zheng static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv, 287e7ffd812SXing Zheng int tx_delay, int rx_delay) 288e7ffd812SXing Zheng { 289e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 290e7ffd812SXing Zheng 291e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 292e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 293e7ffd812SXing Zheng return; 294e7ffd812SXing Zheng } 295e7ffd812SXing Zheng 296e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 297e7ffd812SXing Zheng RK3228_GMAC_PHY_INTF_SEL_RGMII | 298e7ffd812SXing Zheng RK3228_GMAC_RMII_MODE_CLR | 299eaf70ad1SWadim Egorov DELAY_ENABLE(RK3228, tx_delay, rx_delay)); 300e7ffd812SXing Zheng 301e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON0, 302e7ffd812SXing Zheng RK3228_GMAC_CLK_RX_DL_CFG(rx_delay) | 303e7ffd812SXing Zheng RK3228_GMAC_CLK_TX_DL_CFG(tx_delay)); 304e7ffd812SXing Zheng } 305e7ffd812SXing Zheng 306e7ffd812SXing Zheng static void rk3228_set_to_rmii(struct rk_priv_data *bsp_priv) 307e7ffd812SXing Zheng { 308e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 309e7ffd812SXing Zheng 310e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 311e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 312e7ffd812SXing Zheng return; 313e7ffd812SXing Zheng } 314e7ffd812SXing Zheng 315e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 316e7ffd812SXing Zheng RK3228_GMAC_PHY_INTF_SEL_RMII | 317e7ffd812SXing Zheng RK3228_GMAC_RMII_MODE); 318e7ffd812SXing Zheng 319e7ffd812SXing Zheng /* set MAC to RMII mode */ 320e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, GRF_BIT(11)); 321e7ffd812SXing Zheng } 322e7ffd812SXing Zheng 323e7ffd812SXing Zheng static void rk3228_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 324e7ffd812SXing Zheng { 325e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 326e7ffd812SXing Zheng 327e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 328e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 329e7ffd812SXing Zheng return; 330e7ffd812SXing Zheng } 331e7ffd812SXing Zheng 332e7ffd812SXing Zheng if (speed == 10) 333e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 334e7ffd812SXing Zheng RK3228_GMAC_CLK_2_5M); 335e7ffd812SXing Zheng else if (speed == 100) 336e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 337e7ffd812SXing Zheng RK3228_GMAC_CLK_25M); 338e7ffd812SXing Zheng else if (speed == 1000) 339e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 340e7ffd812SXing Zheng RK3228_GMAC_CLK_125M); 341e7ffd812SXing Zheng else 342e7ffd812SXing Zheng dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 343e7ffd812SXing Zheng } 344e7ffd812SXing Zheng 345e7ffd812SXing Zheng static void rk3228_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 346e7ffd812SXing Zheng { 347e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 348e7ffd812SXing Zheng 349e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 350e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 351e7ffd812SXing Zheng return; 352e7ffd812SXing Zheng } 353e7ffd812SXing Zheng 354e7ffd812SXing Zheng if (speed == 10) 355e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 356e7ffd812SXing Zheng RK3228_GMAC_RMII_CLK_2_5M | 357e7ffd812SXing Zheng RK3228_GMAC_SPEED_10M); 358e7ffd812SXing Zheng else if (speed == 100) 359e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 360e7ffd812SXing Zheng RK3228_GMAC_RMII_CLK_25M | 361e7ffd812SXing Zheng RK3228_GMAC_SPEED_100M); 362e7ffd812SXing Zheng else 363e7ffd812SXing Zheng dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 364e7ffd812SXing Zheng } 365e7ffd812SXing Zheng 3666fa12c78SDavid Wu static void rk3228_integrated_phy_powerup(struct rk_priv_data *priv) 3676fa12c78SDavid Wu { 3686fa12c78SDavid Wu regmap_write(priv->grf, RK3228_GRF_CON_MUX, 3696fa12c78SDavid Wu RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY); 3706fa12c78SDavid Wu } 3716fa12c78SDavid Wu 372e7ffd812SXing Zheng static const struct rk_gmac_ops rk3228_ops = { 373e7ffd812SXing Zheng .set_to_rgmii = rk3228_set_to_rgmii, 374e7ffd812SXing Zheng .set_to_rmii = rk3228_set_to_rmii, 375e7ffd812SXing Zheng .set_rgmii_speed = rk3228_set_rgmii_speed, 376e7ffd812SXing Zheng .set_rmii_speed = rk3228_set_rmii_speed, 3776fa12c78SDavid Wu .integrated_phy_powerup = rk3228_integrated_phy_powerup, 378e7ffd812SXing Zheng }; 379e7ffd812SXing Zheng 3807ad269eaSRoger Chen #define RK3288_GRF_SOC_CON1 0x0248 3817ad269eaSRoger Chen #define RK3288_GRF_SOC_CON3 0x0250 3827ad269eaSRoger Chen 3837ad269eaSRoger Chen /*RK3288_GRF_SOC_CON1*/ 3840fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(6) | GRF_CLR_BIT(7) | \ 3850fb98db1SHeiko Stübner GRF_CLR_BIT(8)) 3860fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | \ 3870fb98db1SHeiko Stübner GRF_BIT(8)) 3880fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL GRF_BIT(9) 3890fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(9) 3900fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_10M GRF_CLR_BIT(10) 3910fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_100M GRF_BIT(10) 3920fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_25M GRF_BIT(11) 3930fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(11) 3940fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_125M (GRF_CLR_BIT(12) | GRF_CLR_BIT(13)) 3950fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_25M (GRF_BIT(12) | GRF_BIT(13)) 3960fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_2_5M (GRF_CLR_BIT(12) | GRF_BIT(13)) 3970fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE GRF_BIT(14) 3980fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE_CLR GRF_CLR_BIT(14) 3997ad269eaSRoger Chen 4007ad269eaSRoger Chen /*RK3288_GRF_SOC_CON3*/ 4010fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_ENABLE GRF_BIT(14) 4020fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14) 4030fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 4040fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 4050fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 4060fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 4077ad269eaSRoger Chen 4080fb98db1SHeiko Stübner static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv, 4097ad269eaSRoger Chen int tx_delay, int rx_delay) 4107ad269eaSRoger Chen { 4117ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 4127ad269eaSRoger Chen 4137ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 414d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 4157ad269eaSRoger Chen return; 4167ad269eaSRoger Chen } 4177ad269eaSRoger Chen 4187ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4190fb98db1SHeiko Stübner RK3288_GMAC_PHY_INTF_SEL_RGMII | 4200fb98db1SHeiko Stübner RK3288_GMAC_RMII_MODE_CLR); 4217ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3, 422eaf70ad1SWadim Egorov DELAY_ENABLE(RK3288, tx_delay, rx_delay) | 4230fb98db1SHeiko Stübner RK3288_GMAC_CLK_RX_DL_CFG(rx_delay) | 4240fb98db1SHeiko Stübner RK3288_GMAC_CLK_TX_DL_CFG(tx_delay)); 4257ad269eaSRoger Chen } 4267ad269eaSRoger Chen 4270fb98db1SHeiko Stübner static void rk3288_set_to_rmii(struct rk_priv_data *bsp_priv) 4287ad269eaSRoger Chen { 4297ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 4307ad269eaSRoger Chen 4317ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 432d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 4337ad269eaSRoger Chen return; 4347ad269eaSRoger Chen } 4357ad269eaSRoger Chen 4367ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4370fb98db1SHeiko Stübner RK3288_GMAC_PHY_INTF_SEL_RMII | RK3288_GMAC_RMII_MODE); 4387ad269eaSRoger Chen } 4397ad269eaSRoger Chen 4400fb98db1SHeiko Stübner static void rk3288_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 4417ad269eaSRoger Chen { 4427ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 4437ad269eaSRoger Chen 4447ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 445d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 4467ad269eaSRoger Chen return; 4477ad269eaSRoger Chen } 4487ad269eaSRoger Chen 4497ad269eaSRoger Chen if (speed == 10) 4500fb98db1SHeiko Stübner regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4510fb98db1SHeiko Stübner RK3288_GMAC_CLK_2_5M); 4527ad269eaSRoger Chen else if (speed == 100) 4530fb98db1SHeiko Stübner regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4540fb98db1SHeiko Stübner RK3288_GMAC_CLK_25M); 4557ad269eaSRoger Chen else if (speed == 1000) 4560fb98db1SHeiko Stübner regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4570fb98db1SHeiko Stübner RK3288_GMAC_CLK_125M); 4587ad269eaSRoger Chen else 4597ad269eaSRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 4607ad269eaSRoger Chen } 4617ad269eaSRoger Chen 4620fb98db1SHeiko Stübner static void rk3288_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 4637ad269eaSRoger Chen { 4647ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 4657ad269eaSRoger Chen 4667ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 467d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 4687ad269eaSRoger Chen return; 4697ad269eaSRoger Chen } 4707ad269eaSRoger Chen 4717ad269eaSRoger Chen if (speed == 10) { 4727ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4730fb98db1SHeiko Stübner RK3288_GMAC_RMII_CLK_2_5M | 4740fb98db1SHeiko Stübner RK3288_GMAC_SPEED_10M); 4757ad269eaSRoger Chen } else if (speed == 100) { 4767ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4770fb98db1SHeiko Stübner RK3288_GMAC_RMII_CLK_25M | 4780fb98db1SHeiko Stübner RK3288_GMAC_SPEED_100M); 4797ad269eaSRoger Chen } else { 4807ad269eaSRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 4817ad269eaSRoger Chen } 4827ad269eaSRoger Chen } 4837ad269eaSRoger Chen 48492c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3288_ops = { 4850fb98db1SHeiko Stübner .set_to_rgmii = rk3288_set_to_rgmii, 4860fb98db1SHeiko Stübner .set_to_rmii = rk3288_set_to_rmii, 4870fb98db1SHeiko Stübner .set_rgmii_speed = rk3288_set_rgmii_speed, 4880fb98db1SHeiko Stübner .set_rmii_speed = rk3288_set_rmii_speed, 4890fb98db1SHeiko Stübner }; 4900fb98db1SHeiko Stübner 491b4ac9456STobias Schramm #define RK3308_GRF_MAC_CON0 0x04a0 492b4ac9456STobias Schramm 493b4ac9456STobias Schramm /* RK3308_GRF_MAC_CON0 */ 494b4ac9456STobias Schramm #define RK3308_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(2) | GRF_CLR_BIT(3) | \ 495b4ac9456STobias Schramm GRF_BIT(4)) 496b4ac9456STobias Schramm #define RK3308_GMAC_FLOW_CTRL GRF_BIT(3) 497b4ac9456STobias Schramm #define RK3308_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 498b4ac9456STobias Schramm #define RK3308_GMAC_SPEED_10M GRF_CLR_BIT(0) 499b4ac9456STobias Schramm #define RK3308_GMAC_SPEED_100M GRF_BIT(0) 500b4ac9456STobias Schramm 501b4ac9456STobias Schramm static void rk3308_set_to_rmii(struct rk_priv_data *bsp_priv) 502b4ac9456STobias Schramm { 503b4ac9456STobias Schramm struct device *dev = &bsp_priv->pdev->dev; 504b4ac9456STobias Schramm 505b4ac9456STobias Schramm if (IS_ERR(bsp_priv->grf)) { 506b4ac9456STobias Schramm dev_err(dev, "Missing rockchip,grf property\n"); 507b4ac9456STobias Schramm return; 508b4ac9456STobias Schramm } 509b4ac9456STobias Schramm 510b4ac9456STobias Schramm regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0, 511b4ac9456STobias Schramm RK3308_GMAC_PHY_INTF_SEL_RMII); 512b4ac9456STobias Schramm } 513b4ac9456STobias Schramm 514b4ac9456STobias Schramm static void rk3308_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 515b4ac9456STobias Schramm { 516b4ac9456STobias Schramm struct device *dev = &bsp_priv->pdev->dev; 517b4ac9456STobias Schramm 518b4ac9456STobias Schramm if (IS_ERR(bsp_priv->grf)) { 519b4ac9456STobias Schramm dev_err(dev, "Missing rockchip,grf property\n"); 520b4ac9456STobias Schramm return; 521b4ac9456STobias Schramm } 522b4ac9456STobias Schramm 523b4ac9456STobias Schramm if (speed == 10) { 524b4ac9456STobias Schramm regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0, 525b4ac9456STobias Schramm RK3308_GMAC_SPEED_10M); 526b4ac9456STobias Schramm } else if (speed == 100) { 527b4ac9456STobias Schramm regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0, 528b4ac9456STobias Schramm RK3308_GMAC_SPEED_100M); 529b4ac9456STobias Schramm } else { 530b4ac9456STobias Schramm dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 531b4ac9456STobias Schramm } 532b4ac9456STobias Schramm } 533b4ac9456STobias Schramm 534b4ac9456STobias Schramm static const struct rk_gmac_ops rk3308_ops = { 535b4ac9456STobias Schramm .set_to_rmii = rk3308_set_to_rmii, 536b4ac9456STobias Schramm .set_rmii_speed = rk3308_set_rmii_speed, 537b4ac9456STobias Schramm }; 538b4ac9456STobias Schramm 539d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON0 0x0900 540d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON1 0x0904 5418bdf63bdSDavid Wu #define RK3328_GRF_MAC_CON2 0x0908 5428bdf63bdSDavid Wu #define RK3328_GRF_MACPHY_CON1 0xb04 543d4ff816eSdavid.wu 544d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON0 */ 545d4ff816eSdavid.wu #define RK3328_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 546d4ff816eSdavid.wu #define RK3328_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 547d4ff816eSdavid.wu 548d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON1 */ 549d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RGMII \ 550d4ff816eSdavid.wu (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6)) 551d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RMII \ 552d4ff816eSdavid.wu (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6)) 553d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL GRF_BIT(3) 554d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 555d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_10M GRF_CLR_BIT(2) 556d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_100M GRF_BIT(2) 557d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_25M GRF_BIT(7) 558d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7) 559d4ff816eSdavid.wu #define RK3328_GMAC_CLK_125M (GRF_CLR_BIT(11) | GRF_CLR_BIT(12)) 560d4ff816eSdavid.wu #define RK3328_GMAC_CLK_25M (GRF_BIT(11) | GRF_BIT(12)) 561d4ff816eSdavid.wu #define RK3328_GMAC_CLK_2_5M (GRF_CLR_BIT(11) | GRF_BIT(12)) 562d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE GRF_BIT(9) 563d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE_CLR GRF_CLR_BIT(9) 564d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0) 565d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0) 566d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1) 567d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(0) 568d4ff816eSdavid.wu 5698bdf63bdSDavid Wu /* RK3328_GRF_MACPHY_CON1 */ 5708bdf63bdSDavid Wu #define RK3328_MACPHY_RMII_MODE GRF_BIT(9) 5718bdf63bdSDavid Wu 572d4ff816eSdavid.wu static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv, 573d4ff816eSdavid.wu int tx_delay, int rx_delay) 574d4ff816eSdavid.wu { 575d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev; 576d4ff816eSdavid.wu 577d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) { 578d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n"); 579d4ff816eSdavid.wu return; 580d4ff816eSdavid.wu } 581d4ff816eSdavid.wu 582d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, 583d4ff816eSdavid.wu RK3328_GMAC_PHY_INTF_SEL_RGMII | 584d4ff816eSdavid.wu RK3328_GMAC_RMII_MODE_CLR | 585d4ff816eSdavid.wu RK3328_GMAC_RXCLK_DLY_ENABLE | 586d4ff816eSdavid.wu RK3328_GMAC_TXCLK_DLY_ENABLE); 587d4ff816eSdavid.wu 588d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON0, 589d4ff816eSdavid.wu RK3328_GMAC_CLK_RX_DL_CFG(rx_delay) | 590d4ff816eSdavid.wu RK3328_GMAC_CLK_TX_DL_CFG(tx_delay)); 591d4ff816eSdavid.wu } 592d4ff816eSdavid.wu 593d4ff816eSdavid.wu static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv) 594d4ff816eSdavid.wu { 595d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev; 5968bdf63bdSDavid Wu unsigned int reg; 597d4ff816eSdavid.wu 598d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) { 599d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n"); 600d4ff816eSdavid.wu return; 601d4ff816eSdavid.wu } 602d4ff816eSdavid.wu 6038bdf63bdSDavid Wu reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 : 6048bdf63bdSDavid Wu RK3328_GRF_MAC_CON1; 6058bdf63bdSDavid Wu 6068bdf63bdSDavid Wu regmap_write(bsp_priv->grf, reg, 607d4ff816eSdavid.wu RK3328_GMAC_PHY_INTF_SEL_RMII | 608d4ff816eSdavid.wu RK3328_GMAC_RMII_MODE); 609d4ff816eSdavid.wu } 610d4ff816eSdavid.wu 611d4ff816eSdavid.wu static void rk3328_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 612d4ff816eSdavid.wu { 613d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev; 614d4ff816eSdavid.wu 615d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) { 616d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n"); 617d4ff816eSdavid.wu return; 618d4ff816eSdavid.wu } 619d4ff816eSdavid.wu 620d4ff816eSdavid.wu if (speed == 10) 621d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, 622d4ff816eSdavid.wu RK3328_GMAC_CLK_2_5M); 623d4ff816eSdavid.wu else if (speed == 100) 624d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, 625d4ff816eSdavid.wu RK3328_GMAC_CLK_25M); 626d4ff816eSdavid.wu else if (speed == 1000) 627d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, 628d4ff816eSdavid.wu RK3328_GMAC_CLK_125M); 629d4ff816eSdavid.wu else 630d4ff816eSdavid.wu dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 631d4ff816eSdavid.wu } 632d4ff816eSdavid.wu 633d4ff816eSdavid.wu static void rk3328_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 634d4ff816eSdavid.wu { 635d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev; 6368bdf63bdSDavid Wu unsigned int reg; 637d4ff816eSdavid.wu 638d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) { 639d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n"); 640d4ff816eSdavid.wu return; 641d4ff816eSdavid.wu } 642d4ff816eSdavid.wu 6438bdf63bdSDavid Wu reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 : 6448bdf63bdSDavid Wu RK3328_GRF_MAC_CON1; 6458bdf63bdSDavid Wu 646d4ff816eSdavid.wu if (speed == 10) 6478bdf63bdSDavid Wu regmap_write(bsp_priv->grf, reg, 648d4ff816eSdavid.wu RK3328_GMAC_RMII_CLK_2_5M | 649d4ff816eSdavid.wu RK3328_GMAC_SPEED_10M); 650d4ff816eSdavid.wu else if (speed == 100) 6518bdf63bdSDavid Wu regmap_write(bsp_priv->grf, reg, 652d4ff816eSdavid.wu RK3328_GMAC_RMII_CLK_25M | 653d4ff816eSdavid.wu RK3328_GMAC_SPEED_100M); 654d4ff816eSdavid.wu else 655d4ff816eSdavid.wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 656d4ff816eSdavid.wu } 657d4ff816eSdavid.wu 6588bdf63bdSDavid Wu static void rk3328_integrated_phy_powerup(struct rk_priv_data *priv) 6598bdf63bdSDavid Wu { 6608bdf63bdSDavid Wu regmap_write(priv->grf, RK3328_GRF_MACPHY_CON1, 6618bdf63bdSDavid Wu RK3328_MACPHY_RMII_MODE); 6628bdf63bdSDavid Wu } 6638bdf63bdSDavid Wu 664d4ff816eSdavid.wu static const struct rk_gmac_ops rk3328_ops = { 665d4ff816eSdavid.wu .set_to_rgmii = rk3328_set_to_rgmii, 666d4ff816eSdavid.wu .set_to_rmii = rk3328_set_to_rmii, 667d4ff816eSdavid.wu .set_rgmii_speed = rk3328_set_rgmii_speed, 668d4ff816eSdavid.wu .set_rmii_speed = rk3328_set_rmii_speed, 6698bdf63bdSDavid Wu .integrated_phy_powerup = rk3328_integrated_phy_powerup, 670d4ff816eSdavid.wu }; 671d4ff816eSdavid.wu 672ba289af8SRoger Chen #define RK3366_GRF_SOC_CON6 0x0418 673ba289af8SRoger Chen #define RK3366_GRF_SOC_CON7 0x041c 674ba289af8SRoger Chen 675ba289af8SRoger Chen /* RK3366_GRF_SOC_CON6 */ 676ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 677ba289af8SRoger Chen GRF_CLR_BIT(11)) 678ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 679ba289af8SRoger Chen GRF_BIT(11)) 680ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL GRF_BIT(8) 681ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 682ba289af8SRoger Chen #define RK3366_GMAC_SPEED_10M GRF_CLR_BIT(7) 683ba289af8SRoger Chen #define RK3366_GMAC_SPEED_100M GRF_BIT(7) 684ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_25M GRF_BIT(3) 685ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 686ba289af8SRoger Chen #define RK3366_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 687ba289af8SRoger Chen #define RK3366_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 688ba289af8SRoger Chen #define RK3366_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 689ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE GRF_BIT(6) 690ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 691ba289af8SRoger Chen 692ba289af8SRoger Chen /* RK3366_GRF_SOC_CON7 */ 693ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 694ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 695ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 696ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 697ba289af8SRoger Chen #define RK3366_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 698ba289af8SRoger Chen #define RK3366_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 699ba289af8SRoger Chen 700ba289af8SRoger Chen static void rk3366_set_to_rgmii(struct rk_priv_data *bsp_priv, 701ba289af8SRoger Chen int tx_delay, int rx_delay) 702ba289af8SRoger Chen { 703ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 704ba289af8SRoger Chen 705ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 706ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 707ba289af8SRoger Chen return; 708ba289af8SRoger Chen } 709ba289af8SRoger Chen 710ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 711ba289af8SRoger Chen RK3366_GMAC_PHY_INTF_SEL_RGMII | 712ba289af8SRoger Chen RK3366_GMAC_RMII_MODE_CLR); 713ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON7, 714eaf70ad1SWadim Egorov DELAY_ENABLE(RK3366, tx_delay, rx_delay) | 715ba289af8SRoger Chen RK3366_GMAC_CLK_RX_DL_CFG(rx_delay) | 716ba289af8SRoger Chen RK3366_GMAC_CLK_TX_DL_CFG(tx_delay)); 717ba289af8SRoger Chen } 718ba289af8SRoger Chen 719ba289af8SRoger Chen static void rk3366_set_to_rmii(struct rk_priv_data *bsp_priv) 720ba289af8SRoger Chen { 721ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 722ba289af8SRoger Chen 723ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 724ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 725ba289af8SRoger Chen return; 726ba289af8SRoger Chen } 727ba289af8SRoger Chen 728ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 729ba289af8SRoger Chen RK3366_GMAC_PHY_INTF_SEL_RMII | RK3366_GMAC_RMII_MODE); 730ba289af8SRoger Chen } 731ba289af8SRoger Chen 732ba289af8SRoger Chen static void rk3366_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 733ba289af8SRoger Chen { 734ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 735ba289af8SRoger Chen 736ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 737ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 738ba289af8SRoger Chen return; 739ba289af8SRoger Chen } 740ba289af8SRoger Chen 741ba289af8SRoger Chen if (speed == 10) 742ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 743ba289af8SRoger Chen RK3366_GMAC_CLK_2_5M); 744ba289af8SRoger Chen else if (speed == 100) 745ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 746ba289af8SRoger Chen RK3366_GMAC_CLK_25M); 747ba289af8SRoger Chen else if (speed == 1000) 748ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 749ba289af8SRoger Chen RK3366_GMAC_CLK_125M); 750ba289af8SRoger Chen else 751ba289af8SRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 752ba289af8SRoger Chen } 753ba289af8SRoger Chen 754ba289af8SRoger Chen static void rk3366_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 755ba289af8SRoger Chen { 756ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 757ba289af8SRoger Chen 758ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 759ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 760ba289af8SRoger Chen return; 761ba289af8SRoger Chen } 762ba289af8SRoger Chen 763ba289af8SRoger Chen if (speed == 10) { 764ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 765ba289af8SRoger Chen RK3366_GMAC_RMII_CLK_2_5M | 766ba289af8SRoger Chen RK3366_GMAC_SPEED_10M); 767ba289af8SRoger Chen } else if (speed == 100) { 768ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 769ba289af8SRoger Chen RK3366_GMAC_RMII_CLK_25M | 770ba289af8SRoger Chen RK3366_GMAC_SPEED_100M); 771ba289af8SRoger Chen } else { 772ba289af8SRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 773ba289af8SRoger Chen } 774ba289af8SRoger Chen } 775ba289af8SRoger Chen 776ba289af8SRoger Chen static const struct rk_gmac_ops rk3366_ops = { 777ba289af8SRoger Chen .set_to_rgmii = rk3366_set_to_rgmii, 778ba289af8SRoger Chen .set_to_rmii = rk3366_set_to_rmii, 779ba289af8SRoger Chen .set_rgmii_speed = rk3366_set_rgmii_speed, 780ba289af8SRoger Chen .set_rmii_speed = rk3366_set_rmii_speed, 781ba289af8SRoger Chen }; 782ba289af8SRoger Chen 783df558854SHeiko Stübner #define RK3368_GRF_SOC_CON15 0x043c 784df558854SHeiko Stübner #define RK3368_GRF_SOC_CON16 0x0440 785df558854SHeiko Stübner 786df558854SHeiko Stübner /* RK3368_GRF_SOC_CON15 */ 787df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 788df558854SHeiko Stübner GRF_CLR_BIT(11)) 789df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 790df558854SHeiko Stübner GRF_BIT(11)) 791df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL GRF_BIT(8) 792df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 793df558854SHeiko Stübner #define RK3368_GMAC_SPEED_10M GRF_CLR_BIT(7) 794df558854SHeiko Stübner #define RK3368_GMAC_SPEED_100M GRF_BIT(7) 795df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_25M GRF_BIT(3) 796df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 797df558854SHeiko Stübner #define RK3368_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 798df558854SHeiko Stübner #define RK3368_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 799df558854SHeiko Stübner #define RK3368_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 800df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE GRF_BIT(6) 801df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 802df558854SHeiko Stübner 803df558854SHeiko Stübner /* RK3368_GRF_SOC_CON16 */ 804df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 805df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 806df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 807df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 808df558854SHeiko Stübner #define RK3368_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 809df558854SHeiko Stübner #define RK3368_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 810df558854SHeiko Stübner 811df558854SHeiko Stübner static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv, 812df558854SHeiko Stübner int tx_delay, int rx_delay) 813df558854SHeiko Stübner { 814df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 815df558854SHeiko Stübner 816df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 817df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 818df558854SHeiko Stübner return; 819df558854SHeiko Stübner } 820df558854SHeiko Stübner 821df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 822df558854SHeiko Stübner RK3368_GMAC_PHY_INTF_SEL_RGMII | 823df558854SHeiko Stübner RK3368_GMAC_RMII_MODE_CLR); 824df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16, 825eaf70ad1SWadim Egorov DELAY_ENABLE(RK3368, tx_delay, rx_delay) | 826df558854SHeiko Stübner RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) | 827df558854SHeiko Stübner RK3368_GMAC_CLK_TX_DL_CFG(tx_delay)); 828df558854SHeiko Stübner } 829df558854SHeiko Stübner 830df558854SHeiko Stübner static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv) 831df558854SHeiko Stübner { 832df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 833df558854SHeiko Stübner 834df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 835df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 836df558854SHeiko Stübner return; 837df558854SHeiko Stübner } 838df558854SHeiko Stübner 839df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 840df558854SHeiko Stübner RK3368_GMAC_PHY_INTF_SEL_RMII | RK3368_GMAC_RMII_MODE); 841df558854SHeiko Stübner } 842df558854SHeiko Stübner 843df558854SHeiko Stübner static void rk3368_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 844df558854SHeiko Stübner { 845df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 846df558854SHeiko Stübner 847df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 848df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 849df558854SHeiko Stübner return; 850df558854SHeiko Stübner } 851df558854SHeiko Stübner 852df558854SHeiko Stübner if (speed == 10) 853df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 854df558854SHeiko Stübner RK3368_GMAC_CLK_2_5M); 855df558854SHeiko Stübner else if (speed == 100) 856df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 857df558854SHeiko Stübner RK3368_GMAC_CLK_25M); 858df558854SHeiko Stübner else if (speed == 1000) 859df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 860df558854SHeiko Stübner RK3368_GMAC_CLK_125M); 861df558854SHeiko Stübner else 862df558854SHeiko Stübner dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 863df558854SHeiko Stübner } 864df558854SHeiko Stübner 865df558854SHeiko Stübner static void rk3368_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 866df558854SHeiko Stübner { 867df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 868df558854SHeiko Stübner 869df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 870df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 871df558854SHeiko Stübner return; 872df558854SHeiko Stübner } 873df558854SHeiko Stübner 874df558854SHeiko Stübner if (speed == 10) { 875df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 876df558854SHeiko Stübner RK3368_GMAC_RMII_CLK_2_5M | 877df558854SHeiko Stübner RK3368_GMAC_SPEED_10M); 878df558854SHeiko Stübner } else if (speed == 100) { 879df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 880df558854SHeiko Stübner RK3368_GMAC_RMII_CLK_25M | 881df558854SHeiko Stübner RK3368_GMAC_SPEED_100M); 882df558854SHeiko Stübner } else { 883df558854SHeiko Stübner dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 884df558854SHeiko Stübner } 885df558854SHeiko Stübner } 886df558854SHeiko Stübner 88792c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3368_ops = { 888df558854SHeiko Stübner .set_to_rgmii = rk3368_set_to_rgmii, 889df558854SHeiko Stübner .set_to_rmii = rk3368_set_to_rmii, 890df558854SHeiko Stübner .set_rgmii_speed = rk3368_set_rgmii_speed, 891df558854SHeiko Stübner .set_rmii_speed = rk3368_set_rmii_speed, 892df558854SHeiko Stübner }; 893df558854SHeiko Stübner 894ba289af8SRoger Chen #define RK3399_GRF_SOC_CON5 0xc214 895ba289af8SRoger Chen #define RK3399_GRF_SOC_CON6 0xc218 896ba289af8SRoger Chen 897ba289af8SRoger Chen /* RK3399_GRF_SOC_CON5 */ 898ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 899ba289af8SRoger Chen GRF_CLR_BIT(11)) 900ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 901ba289af8SRoger Chen GRF_BIT(11)) 902ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL GRF_BIT(8) 903ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 904ba289af8SRoger Chen #define RK3399_GMAC_SPEED_10M GRF_CLR_BIT(7) 905ba289af8SRoger Chen #define RK3399_GMAC_SPEED_100M GRF_BIT(7) 906ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_25M GRF_BIT(3) 907ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 908ba289af8SRoger Chen #define RK3399_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 909ba289af8SRoger Chen #define RK3399_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 910ba289af8SRoger Chen #define RK3399_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 911ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE GRF_BIT(6) 912ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 913ba289af8SRoger Chen 914ba289af8SRoger Chen /* RK3399_GRF_SOC_CON6 */ 915ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 916ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 917ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 918ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 919ba289af8SRoger Chen #define RK3399_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 920ba289af8SRoger Chen #define RK3399_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 921ba289af8SRoger Chen 922ba289af8SRoger Chen static void rk3399_set_to_rgmii(struct rk_priv_data *bsp_priv, 923ba289af8SRoger Chen int tx_delay, int rx_delay) 924ba289af8SRoger Chen { 925ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 926ba289af8SRoger Chen 927ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 928ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 929ba289af8SRoger Chen return; 930ba289af8SRoger Chen } 931ba289af8SRoger Chen 932ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 933ba289af8SRoger Chen RK3399_GMAC_PHY_INTF_SEL_RGMII | 934ba289af8SRoger Chen RK3399_GMAC_RMII_MODE_CLR); 935ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON6, 936eaf70ad1SWadim Egorov DELAY_ENABLE(RK3399, tx_delay, rx_delay) | 937ba289af8SRoger Chen RK3399_GMAC_CLK_RX_DL_CFG(rx_delay) | 938ba289af8SRoger Chen RK3399_GMAC_CLK_TX_DL_CFG(tx_delay)); 939ba289af8SRoger Chen } 940ba289af8SRoger Chen 941ba289af8SRoger Chen static void rk3399_set_to_rmii(struct rk_priv_data *bsp_priv) 942ba289af8SRoger Chen { 943ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 944ba289af8SRoger Chen 945ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 946ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 947ba289af8SRoger Chen return; 948ba289af8SRoger Chen } 949ba289af8SRoger Chen 950ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 951ba289af8SRoger Chen RK3399_GMAC_PHY_INTF_SEL_RMII | RK3399_GMAC_RMII_MODE); 952ba289af8SRoger Chen } 953ba289af8SRoger Chen 954ba289af8SRoger Chen static void rk3399_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 955ba289af8SRoger Chen { 956ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 957ba289af8SRoger Chen 958ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 959ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 960ba289af8SRoger Chen return; 961ba289af8SRoger Chen } 962ba289af8SRoger Chen 963ba289af8SRoger Chen if (speed == 10) 964ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 965ba289af8SRoger Chen RK3399_GMAC_CLK_2_5M); 966ba289af8SRoger Chen else if (speed == 100) 967ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 968ba289af8SRoger Chen RK3399_GMAC_CLK_25M); 969ba289af8SRoger Chen else if (speed == 1000) 970ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 971ba289af8SRoger Chen RK3399_GMAC_CLK_125M); 972ba289af8SRoger Chen else 973ba289af8SRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 974ba289af8SRoger Chen } 975ba289af8SRoger Chen 976ba289af8SRoger Chen static void rk3399_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 977ba289af8SRoger Chen { 978ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 979ba289af8SRoger Chen 980ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 981ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 982ba289af8SRoger Chen return; 983ba289af8SRoger Chen } 984ba289af8SRoger Chen 985ba289af8SRoger Chen if (speed == 10) { 986ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 987ba289af8SRoger Chen RK3399_GMAC_RMII_CLK_2_5M | 988ba289af8SRoger Chen RK3399_GMAC_SPEED_10M); 989ba289af8SRoger Chen } else if (speed == 100) { 990ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 991ba289af8SRoger Chen RK3399_GMAC_RMII_CLK_25M | 992ba289af8SRoger Chen RK3399_GMAC_SPEED_100M); 993ba289af8SRoger Chen } else { 994ba289af8SRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 995ba289af8SRoger Chen } 996ba289af8SRoger Chen } 997ba289af8SRoger Chen 998ba289af8SRoger Chen static const struct rk_gmac_ops rk3399_ops = { 999ba289af8SRoger Chen .set_to_rgmii = rk3399_set_to_rgmii, 1000ba289af8SRoger Chen .set_to_rmii = rk3399_set_to_rmii, 1001ba289af8SRoger Chen .set_rgmii_speed = rk3399_set_rgmii_speed, 1002ba289af8SRoger Chen .set_rmii_speed = rk3399_set_rmii_speed, 1003ba289af8SRoger Chen }; 1004ba289af8SRoger Chen 10053bb3d6b1SDavid Wu #define RK3568_GRF_GMAC0_CON0 0x0380 10063bb3d6b1SDavid Wu #define RK3568_GRF_GMAC0_CON1 0x0384 10073bb3d6b1SDavid Wu #define RK3568_GRF_GMAC1_CON0 0x0388 10083bb3d6b1SDavid Wu #define RK3568_GRF_GMAC1_CON1 0x038c 10093bb3d6b1SDavid Wu 10103bb3d6b1SDavid Wu /* RK3568_GRF_GMAC0_CON1 && RK3568_GRF_GMAC1_CON1 */ 10113bb3d6b1SDavid Wu #define RK3568_GMAC_PHY_INTF_SEL_RGMII \ 10123bb3d6b1SDavid Wu (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6)) 10133bb3d6b1SDavid Wu #define RK3568_GMAC_PHY_INTF_SEL_RMII \ 10143bb3d6b1SDavid Wu (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6)) 10153bb3d6b1SDavid Wu #define RK3568_GMAC_FLOW_CTRL GRF_BIT(3) 10163bb3d6b1SDavid Wu #define RK3568_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 10173bb3d6b1SDavid Wu #define RK3568_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1) 10183bb3d6b1SDavid Wu #define RK3568_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(1) 10193bb3d6b1SDavid Wu #define RK3568_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0) 10203bb3d6b1SDavid Wu #define RK3568_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0) 10213bb3d6b1SDavid Wu 10223bb3d6b1SDavid Wu /* RK3568_GRF_GMAC0_CON0 && RK3568_GRF_GMAC1_CON0 */ 10233bb3d6b1SDavid Wu #define RK3568_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 10243bb3d6b1SDavid Wu #define RK3568_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 10253bb3d6b1SDavid Wu 10263bb3d6b1SDavid Wu static void rk3568_set_to_rgmii(struct rk_priv_data *bsp_priv, 10273bb3d6b1SDavid Wu int tx_delay, int rx_delay) 10283bb3d6b1SDavid Wu { 10293bb3d6b1SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 10303bb3d6b1SDavid Wu u32 con0, con1; 10313bb3d6b1SDavid Wu 10323bb3d6b1SDavid Wu if (IS_ERR(bsp_priv->grf)) { 10333bb3d6b1SDavid Wu dev_err(dev, "Missing rockchip,grf property\n"); 10343bb3d6b1SDavid Wu return; 10353bb3d6b1SDavid Wu } 10363bb3d6b1SDavid Wu 10373bb3d6b1SDavid Wu con0 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON0 : 10383bb3d6b1SDavid Wu RK3568_GRF_GMAC0_CON0; 10393bb3d6b1SDavid Wu con1 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON1 : 10403bb3d6b1SDavid Wu RK3568_GRF_GMAC0_CON1; 10413bb3d6b1SDavid Wu 10423bb3d6b1SDavid Wu regmap_write(bsp_priv->grf, con0, 10433bb3d6b1SDavid Wu RK3568_GMAC_CLK_RX_DL_CFG(rx_delay) | 10443bb3d6b1SDavid Wu RK3568_GMAC_CLK_TX_DL_CFG(tx_delay)); 10453bb3d6b1SDavid Wu 10463bb3d6b1SDavid Wu regmap_write(bsp_priv->grf, con1, 10473bb3d6b1SDavid Wu RK3568_GMAC_PHY_INTF_SEL_RGMII | 10483bb3d6b1SDavid Wu RK3568_GMAC_RXCLK_DLY_ENABLE | 10493bb3d6b1SDavid Wu RK3568_GMAC_TXCLK_DLY_ENABLE); 10503bb3d6b1SDavid Wu } 10513bb3d6b1SDavid Wu 10523bb3d6b1SDavid Wu static void rk3568_set_to_rmii(struct rk_priv_data *bsp_priv) 10533bb3d6b1SDavid Wu { 10543bb3d6b1SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 10553bb3d6b1SDavid Wu u32 con1; 10563bb3d6b1SDavid Wu 10573bb3d6b1SDavid Wu if (IS_ERR(bsp_priv->grf)) { 10583bb3d6b1SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 10593bb3d6b1SDavid Wu return; 10603bb3d6b1SDavid Wu } 10613bb3d6b1SDavid Wu 10623bb3d6b1SDavid Wu con1 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON1 : 10633bb3d6b1SDavid Wu RK3568_GRF_GMAC0_CON1; 10643bb3d6b1SDavid Wu regmap_write(bsp_priv->grf, con1, RK3568_GMAC_PHY_INTF_SEL_RMII); 10653bb3d6b1SDavid Wu } 10663bb3d6b1SDavid Wu 10673bb3d6b1SDavid Wu static void rk3568_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed) 10683bb3d6b1SDavid Wu { 10693bb3d6b1SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 10703bb3d6b1SDavid Wu unsigned long rate; 10713bb3d6b1SDavid Wu int ret; 10723bb3d6b1SDavid Wu 10733bb3d6b1SDavid Wu switch (speed) { 10743bb3d6b1SDavid Wu case 10: 10753bb3d6b1SDavid Wu rate = 2500000; 10763bb3d6b1SDavid Wu break; 10773bb3d6b1SDavid Wu case 100: 10783bb3d6b1SDavid Wu rate = 25000000; 10793bb3d6b1SDavid Wu break; 10803bb3d6b1SDavid Wu case 1000: 10813bb3d6b1SDavid Wu rate = 125000000; 10823bb3d6b1SDavid Wu break; 10833bb3d6b1SDavid Wu default: 10843bb3d6b1SDavid Wu dev_err(dev, "unknown speed value for GMAC speed=%d", speed); 10853bb3d6b1SDavid Wu return; 10863bb3d6b1SDavid Wu } 10873bb3d6b1SDavid Wu 10883bb3d6b1SDavid Wu ret = clk_set_rate(bsp_priv->clk_mac_speed, rate); 10893bb3d6b1SDavid Wu if (ret) 10903bb3d6b1SDavid Wu dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n", 10913bb3d6b1SDavid Wu __func__, rate, ret); 10923bb3d6b1SDavid Wu } 10933bb3d6b1SDavid Wu 10943bb3d6b1SDavid Wu static const struct rk_gmac_ops rk3568_ops = { 10953bb3d6b1SDavid Wu .set_to_rgmii = rk3568_set_to_rgmii, 10963bb3d6b1SDavid Wu .set_to_rmii = rk3568_set_to_rmii, 10973bb3d6b1SDavid Wu .set_rgmii_speed = rk3568_set_gmac_speed, 10983bb3d6b1SDavid Wu .set_rmii_speed = rk3568_set_gmac_speed, 10990546b224SJohn Keeping .regs_valid = true, 11003bb3d6b1SDavid Wu .regs = { 11013bb3d6b1SDavid Wu 0xfe2a0000, /* gmac0 */ 11023bb3d6b1SDavid Wu 0xfe010000, /* gmac1 */ 11033bb3d6b1SDavid Wu 0x0, /* sentinel */ 11043bb3d6b1SDavid Wu }, 11053bb3d6b1SDavid Wu }; 11063bb3d6b1SDavid Wu 11072f2b60a0SDavid Wu /* sys_grf */ 11082f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON7 0X031c 11092f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON8 0X0320 11102f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON9 0X0324 11112f2b60a0SDavid Wu 11122f2b60a0SDavid Wu #define RK3588_GMAC_RXCLK_DLY_ENABLE(id) GRF_BIT(2 * (id) + 3) 11132f2b60a0SDavid Wu #define RK3588_GMAC_RXCLK_DLY_DISABLE(id) GRF_CLR_BIT(2 * (id) + 3) 11142f2b60a0SDavid Wu #define RK3588_GMAC_TXCLK_DLY_ENABLE(id) GRF_BIT(2 * (id) + 2) 11152f2b60a0SDavid Wu #define RK3588_GMAC_TXCLK_DLY_DISABLE(id) GRF_CLR_BIT(2 * (id) + 2) 11162f2b60a0SDavid Wu 11172f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0xFF, 8) 11182f2b60a0SDavid Wu #define RK3588_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0xFF, 0) 11192f2b60a0SDavid Wu 11202f2b60a0SDavid Wu /* php_grf */ 11212f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON0 0X0008 11222f2b60a0SDavid Wu #define RK3588_GRF_CLK_CON1 0X0070 11232f2b60a0SDavid Wu 11242f2b60a0SDavid Wu #define RK3588_GMAC_PHY_INTF_SEL_RGMII(id) \ 11252f2b60a0SDavid Wu (GRF_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_CLR_BIT(5 + (id) * 6)) 11262f2b60a0SDavid Wu #define RK3588_GMAC_PHY_INTF_SEL_RMII(id) \ 11272f2b60a0SDavid Wu (GRF_CLR_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_BIT(5 + (id) * 6)) 11282f2b60a0SDavid Wu 11292f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RMII_MODE(id) GRF_BIT(5 * (id)) 11302f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_MODE(id) GRF_CLR_BIT(5 * (id)) 11312f2b60a0SDavid Wu 11322f2b60a0SDavid Wu #define RK3588_GMAC_CLK_SELET_CRU(id) GRF_BIT(5 * (id) + 4) 11332f2b60a0SDavid Wu #define RK3588_GMAC_CLK_SELET_IO(id) GRF_CLR_BIT(5 * (id) + 4) 11342f2b60a0SDavid Wu 11352f2b60a0SDavid Wu #define RK3588_GMA_CLK_RMII_DIV2(id) GRF_BIT(5 * (id) + 2) 11362f2b60a0SDavid Wu #define RK3588_GMA_CLK_RMII_DIV20(id) GRF_CLR_BIT(5 * (id) + 2) 11372f2b60a0SDavid Wu 11382f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_DIV1(id) \ 11392f2b60a0SDavid Wu (GRF_CLR_BIT(5 * (id) + 2) | GRF_CLR_BIT(5 * (id) + 3)) 11402f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_DIV5(id) \ 11412f2b60a0SDavid Wu (GRF_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3)) 11422f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_DIV50(id) \ 11432f2b60a0SDavid Wu (GRF_CLR_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3)) 11442f2b60a0SDavid Wu 11452f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RMII_GATE(id) GRF_BIT(5 * (id) + 1) 11462f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RMII_NOGATE(id) GRF_CLR_BIT(5 * (id) + 1) 11472f2b60a0SDavid Wu 11482f2b60a0SDavid Wu static void rk3588_set_to_rgmii(struct rk_priv_data *bsp_priv, 11492f2b60a0SDavid Wu int tx_delay, int rx_delay) 11502f2b60a0SDavid Wu { 11512f2b60a0SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 11522f2b60a0SDavid Wu u32 offset_con, id = bsp_priv->id; 11532f2b60a0SDavid Wu 11542f2b60a0SDavid Wu if (IS_ERR(bsp_priv->grf) || IS_ERR(bsp_priv->php_grf)) { 11552f2b60a0SDavid Wu dev_err(dev, "Missing rockchip,grf or rockchip,php_grf property\n"); 11562f2b60a0SDavid Wu return; 11572f2b60a0SDavid Wu } 11582f2b60a0SDavid Wu 11592f2b60a0SDavid Wu offset_con = bsp_priv->id == 1 ? RK3588_GRF_GMAC_CON9 : 11602f2b60a0SDavid Wu RK3588_GRF_GMAC_CON8; 11612f2b60a0SDavid Wu 11622f2b60a0SDavid Wu regmap_write(bsp_priv->php_grf, RK3588_GRF_GMAC_CON0, 11632f2b60a0SDavid Wu RK3588_GMAC_PHY_INTF_SEL_RGMII(id)); 11642f2b60a0SDavid Wu 11652f2b60a0SDavid Wu regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, 11662f2b60a0SDavid Wu RK3588_GMAC_CLK_RGMII_MODE(id)); 11672f2b60a0SDavid Wu 11682f2b60a0SDavid Wu regmap_write(bsp_priv->grf, RK3588_GRF_GMAC_CON7, 11692f2b60a0SDavid Wu RK3588_GMAC_RXCLK_DLY_ENABLE(id) | 11702f2b60a0SDavid Wu RK3588_GMAC_TXCLK_DLY_ENABLE(id)); 11712f2b60a0SDavid Wu 11722f2b60a0SDavid Wu regmap_write(bsp_priv->grf, offset_con, 11732f2b60a0SDavid Wu RK3588_GMAC_CLK_RX_DL_CFG(rx_delay) | 11742f2b60a0SDavid Wu RK3588_GMAC_CLK_TX_DL_CFG(tx_delay)); 11752f2b60a0SDavid Wu } 11762f2b60a0SDavid Wu 11772f2b60a0SDavid Wu static void rk3588_set_to_rmii(struct rk_priv_data *bsp_priv) 11782f2b60a0SDavid Wu { 11792f2b60a0SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 11802f2b60a0SDavid Wu 11812f2b60a0SDavid Wu if (IS_ERR(bsp_priv->php_grf)) { 11822f2b60a0SDavid Wu dev_err(dev, "%s: Missing rockchip,php_grf property\n", __func__); 11832f2b60a0SDavid Wu return; 11842f2b60a0SDavid Wu } 11852f2b60a0SDavid Wu 11862f2b60a0SDavid Wu regmap_write(bsp_priv->php_grf, RK3588_GRF_GMAC_CON0, 11872f2b60a0SDavid Wu RK3588_GMAC_PHY_INTF_SEL_RMII(bsp_priv->id)); 11882f2b60a0SDavid Wu 11892f2b60a0SDavid Wu regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, 11902f2b60a0SDavid Wu RK3588_GMAC_CLK_RMII_MODE(bsp_priv->id)); 11912f2b60a0SDavid Wu } 11922f2b60a0SDavid Wu 11932f2b60a0SDavid Wu static void rk3588_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed) 11942f2b60a0SDavid Wu { 11952f2b60a0SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 11962f2b60a0SDavid Wu unsigned int val = 0, id = bsp_priv->id; 11972f2b60a0SDavid Wu 11982f2b60a0SDavid Wu switch (speed) { 11992f2b60a0SDavid Wu case 10: 12002f2b60a0SDavid Wu if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) 12012f2b60a0SDavid Wu val = RK3588_GMA_CLK_RMII_DIV20(id); 12022f2b60a0SDavid Wu else 12032f2b60a0SDavid Wu val = RK3588_GMAC_CLK_RGMII_DIV50(id); 12042f2b60a0SDavid Wu break; 12052f2b60a0SDavid Wu case 100: 12062f2b60a0SDavid Wu if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) 12072f2b60a0SDavid Wu val = RK3588_GMA_CLK_RMII_DIV2(id); 12082f2b60a0SDavid Wu else 12092f2b60a0SDavid Wu val = RK3588_GMAC_CLK_RGMII_DIV5(id); 12102f2b60a0SDavid Wu break; 12112f2b60a0SDavid Wu case 1000: 12122f2b60a0SDavid Wu if (bsp_priv->phy_iface != PHY_INTERFACE_MODE_RMII) 12132f2b60a0SDavid Wu val = RK3588_GMAC_CLK_RGMII_DIV1(id); 12142f2b60a0SDavid Wu else 12152f2b60a0SDavid Wu goto err; 12162f2b60a0SDavid Wu break; 12172f2b60a0SDavid Wu default: 12182f2b60a0SDavid Wu goto err; 12192f2b60a0SDavid Wu } 12202f2b60a0SDavid Wu 12212f2b60a0SDavid Wu regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, val); 12222f2b60a0SDavid Wu 12232f2b60a0SDavid Wu return; 12242f2b60a0SDavid Wu err: 12252f2b60a0SDavid Wu dev_err(dev, "unknown speed value for GMAC speed=%d", speed); 12262f2b60a0SDavid Wu } 12272f2b60a0SDavid Wu 12282f2b60a0SDavid Wu static void rk3588_set_clock_selection(struct rk_priv_data *bsp_priv, bool input, 12292f2b60a0SDavid Wu bool enable) 12302f2b60a0SDavid Wu { 12312f2b60a0SDavid Wu unsigned int val = input ? RK3588_GMAC_CLK_SELET_IO(bsp_priv->id) : 12322f2b60a0SDavid Wu RK3588_GMAC_CLK_SELET_CRU(bsp_priv->id); 12332f2b60a0SDavid Wu 12342f2b60a0SDavid Wu val |= enable ? RK3588_GMAC_CLK_RMII_NOGATE(bsp_priv->id) : 12352f2b60a0SDavid Wu RK3588_GMAC_CLK_RMII_GATE(bsp_priv->id); 12362f2b60a0SDavid Wu 12372f2b60a0SDavid Wu regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, val); 12382f2b60a0SDavid Wu } 12392f2b60a0SDavid Wu 12402f2b60a0SDavid Wu static const struct rk_gmac_ops rk3588_ops = { 12412f2b60a0SDavid Wu .set_to_rgmii = rk3588_set_to_rgmii, 12422f2b60a0SDavid Wu .set_to_rmii = rk3588_set_to_rmii, 12432f2b60a0SDavid Wu .set_rgmii_speed = rk3588_set_gmac_speed, 12442f2b60a0SDavid Wu .set_rmii_speed = rk3588_set_gmac_speed, 12452f2b60a0SDavid Wu .set_clock_selection = rk3588_set_clock_selection, 124688619e77SBenjamin Gaignard .regs_valid = true, 124788619e77SBenjamin Gaignard .regs = { 124888619e77SBenjamin Gaignard 0xfe1b0000, /* gmac0 */ 124988619e77SBenjamin Gaignard 0xfe1c0000, /* gmac1 */ 125088619e77SBenjamin Gaignard 0x0, /* sentinel */ 125188619e77SBenjamin Gaignard }, 12522f2b60a0SDavid Wu }; 12532f2b60a0SDavid Wu 125489c9c163SDavid Wu #define RV1108_GRF_GMAC_CON0 0X0900 125589c9c163SDavid Wu 125689c9c163SDavid Wu /* RV1108_GRF_GMAC_CON0 */ 125789c9c163SDavid Wu #define RV1108_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \ 125889c9c163SDavid Wu GRF_BIT(6)) 125989c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL GRF_BIT(3) 126089c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 126189c9c163SDavid Wu #define RV1108_GMAC_SPEED_10M GRF_CLR_BIT(2) 126289c9c163SDavid Wu #define RV1108_GMAC_SPEED_100M GRF_BIT(2) 126389c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_25M GRF_BIT(7) 126489c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7) 126589c9c163SDavid Wu 126689c9c163SDavid Wu static void rv1108_set_to_rmii(struct rk_priv_data *bsp_priv) 126789c9c163SDavid Wu { 126889c9c163SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 126989c9c163SDavid Wu 127089c9c163SDavid Wu if (IS_ERR(bsp_priv->grf)) { 127189c9c163SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 127289c9c163SDavid Wu return; 127389c9c163SDavid Wu } 127489c9c163SDavid Wu 127589c9c163SDavid Wu regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0, 127689c9c163SDavid Wu RV1108_GMAC_PHY_INTF_SEL_RMII); 127789c9c163SDavid Wu } 127889c9c163SDavid Wu 127989c9c163SDavid Wu static void rv1108_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 128089c9c163SDavid Wu { 128189c9c163SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 128289c9c163SDavid Wu 128389c9c163SDavid Wu if (IS_ERR(bsp_priv->grf)) { 128489c9c163SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 128589c9c163SDavid Wu return; 128689c9c163SDavid Wu } 128789c9c163SDavid Wu 128889c9c163SDavid Wu if (speed == 10) { 128989c9c163SDavid Wu regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0, 129089c9c163SDavid Wu RV1108_GMAC_RMII_CLK_2_5M | 129189c9c163SDavid Wu RV1108_GMAC_SPEED_10M); 129289c9c163SDavid Wu } else if (speed == 100) { 129389c9c163SDavid Wu regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0, 129489c9c163SDavid Wu RV1108_GMAC_RMII_CLK_25M | 129589c9c163SDavid Wu RV1108_GMAC_SPEED_100M); 129689c9c163SDavid Wu } else { 129789c9c163SDavid Wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 129889c9c163SDavid Wu } 129989c9c163SDavid Wu } 130089c9c163SDavid Wu 130189c9c163SDavid Wu static const struct rk_gmac_ops rv1108_ops = { 130289c9c163SDavid Wu .set_to_rmii = rv1108_set_to_rmii, 130389c9c163SDavid Wu .set_rmii_speed = rv1108_set_rmii_speed, 130489c9c163SDavid Wu }; 130589c9c163SDavid Wu 1306c931b060SAnand Moon #define RV1126_GRF_GMAC_CON0 0X0070 1307c931b060SAnand Moon #define RV1126_GRF_GMAC_CON1 0X0074 1308c931b060SAnand Moon #define RV1126_GRF_GMAC_CON2 0X0078 1309c931b060SAnand Moon 1310c931b060SAnand Moon /* RV1126_GRF_GMAC_CON0 */ 1311c931b060SAnand Moon #define RV1126_GMAC_PHY_INTF_SEL_RGMII \ 1312c931b060SAnand Moon (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6)) 1313c931b060SAnand Moon #define RV1126_GMAC_PHY_INTF_SEL_RMII \ 1314c931b060SAnand Moon (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6)) 1315c931b060SAnand Moon #define RV1126_GMAC_FLOW_CTRL GRF_BIT(7) 1316c931b060SAnand Moon #define RV1126_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(7) 1317c931b060SAnand Moon #define RV1126_GMAC_M0_RXCLK_DLY_ENABLE GRF_BIT(1) 1318c931b060SAnand Moon #define RV1126_GMAC_M0_RXCLK_DLY_DISABLE GRF_CLR_BIT(1) 1319c931b060SAnand Moon #define RV1126_GMAC_M0_TXCLK_DLY_ENABLE GRF_BIT(0) 1320c931b060SAnand Moon #define RV1126_GMAC_M0_TXCLK_DLY_DISABLE GRF_CLR_BIT(0) 1321c931b060SAnand Moon #define RV1126_GMAC_M1_RXCLK_DLY_ENABLE GRF_BIT(3) 1322c931b060SAnand Moon #define RV1126_GMAC_M1_RXCLK_DLY_DISABLE GRF_CLR_BIT(3) 1323c931b060SAnand Moon #define RV1126_GMAC_M1_TXCLK_DLY_ENABLE GRF_BIT(2) 1324c931b060SAnand Moon #define RV1126_GMAC_M1_TXCLK_DLY_DISABLE GRF_CLR_BIT(2) 1325c931b060SAnand Moon 1326c931b060SAnand Moon /* RV1126_GRF_GMAC_CON1 */ 1327c931b060SAnand Moon #define RV1126_GMAC_M0_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 1328c931b060SAnand Moon #define RV1126_GMAC_M0_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 1329c931b060SAnand Moon /* RV1126_GRF_GMAC_CON2 */ 1330c931b060SAnand Moon #define RV1126_GMAC_M1_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 1331c931b060SAnand Moon #define RV1126_GMAC_M1_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 1332c931b060SAnand Moon 1333c931b060SAnand Moon static void rv1126_set_to_rgmii(struct rk_priv_data *bsp_priv, 1334c931b060SAnand Moon int tx_delay, int rx_delay) 1335c931b060SAnand Moon { 1336c931b060SAnand Moon struct device *dev = &bsp_priv->pdev->dev; 1337c931b060SAnand Moon 1338c931b060SAnand Moon if (IS_ERR(bsp_priv->grf)) { 1339c931b060SAnand Moon dev_err(dev, "Missing rockchip,grf property\n"); 1340c931b060SAnand Moon return; 1341c931b060SAnand Moon } 1342c931b060SAnand Moon 1343c931b060SAnand Moon regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON0, 1344c931b060SAnand Moon RV1126_GMAC_PHY_INTF_SEL_RGMII | 1345c931b060SAnand Moon RV1126_GMAC_M0_RXCLK_DLY_ENABLE | 1346c931b060SAnand Moon RV1126_GMAC_M0_TXCLK_DLY_ENABLE | 1347c931b060SAnand Moon RV1126_GMAC_M1_RXCLK_DLY_ENABLE | 1348c931b060SAnand Moon RV1126_GMAC_M1_TXCLK_DLY_ENABLE); 1349c931b060SAnand Moon 1350c931b060SAnand Moon regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON1, 1351c931b060SAnand Moon RV1126_GMAC_M0_CLK_RX_DL_CFG(rx_delay) | 1352c931b060SAnand Moon RV1126_GMAC_M0_CLK_TX_DL_CFG(tx_delay)); 1353c931b060SAnand Moon 1354c931b060SAnand Moon regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON2, 1355c931b060SAnand Moon RV1126_GMAC_M1_CLK_RX_DL_CFG(rx_delay) | 1356c931b060SAnand Moon RV1126_GMAC_M1_CLK_TX_DL_CFG(tx_delay)); 1357c931b060SAnand Moon } 1358c931b060SAnand Moon 1359c931b060SAnand Moon static void rv1126_set_to_rmii(struct rk_priv_data *bsp_priv) 1360c931b060SAnand Moon { 1361c931b060SAnand Moon struct device *dev = &bsp_priv->pdev->dev; 1362c931b060SAnand Moon 1363c931b060SAnand Moon if (IS_ERR(bsp_priv->grf)) { 1364c931b060SAnand Moon dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 1365c931b060SAnand Moon return; 1366c931b060SAnand Moon } 1367c931b060SAnand Moon 1368c931b060SAnand Moon regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON0, 1369c931b060SAnand Moon RV1126_GMAC_PHY_INTF_SEL_RMII); 1370c931b060SAnand Moon } 1371c931b060SAnand Moon 1372c931b060SAnand Moon static void rv1126_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 1373c931b060SAnand Moon { 1374c931b060SAnand Moon struct device *dev = &bsp_priv->pdev->dev; 1375c931b060SAnand Moon unsigned long rate; 1376c931b060SAnand Moon int ret; 1377c931b060SAnand Moon 1378c931b060SAnand Moon switch (speed) { 1379c931b060SAnand Moon case 10: 1380c931b060SAnand Moon rate = 2500000; 1381c931b060SAnand Moon break; 1382c931b060SAnand Moon case 100: 1383c931b060SAnand Moon rate = 25000000; 1384c931b060SAnand Moon break; 1385c931b060SAnand Moon case 1000: 1386c931b060SAnand Moon rate = 125000000; 1387c931b060SAnand Moon break; 1388c931b060SAnand Moon default: 1389c931b060SAnand Moon dev_err(dev, "unknown speed value for RGMII speed=%d", speed); 1390c931b060SAnand Moon return; 1391c931b060SAnand Moon } 1392c931b060SAnand Moon 1393c931b060SAnand Moon ret = clk_set_rate(bsp_priv->clk_mac_speed, rate); 1394c931b060SAnand Moon if (ret) 1395c931b060SAnand Moon dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n", 1396c931b060SAnand Moon __func__, rate, ret); 1397c931b060SAnand Moon } 1398c931b060SAnand Moon 1399c931b060SAnand Moon static void rv1126_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 1400c931b060SAnand Moon { 1401c931b060SAnand Moon struct device *dev = &bsp_priv->pdev->dev; 1402c931b060SAnand Moon unsigned long rate; 1403c931b060SAnand Moon int ret; 1404c931b060SAnand Moon 1405c931b060SAnand Moon switch (speed) { 1406c931b060SAnand Moon case 10: 1407c931b060SAnand Moon rate = 2500000; 1408c931b060SAnand Moon break; 1409c931b060SAnand Moon case 100: 1410c931b060SAnand Moon rate = 25000000; 1411c931b060SAnand Moon break; 1412c931b060SAnand Moon default: 1413c931b060SAnand Moon dev_err(dev, "unknown speed value for RGMII speed=%d", speed); 1414c931b060SAnand Moon return; 1415c931b060SAnand Moon } 1416c931b060SAnand Moon 1417c931b060SAnand Moon ret = clk_set_rate(bsp_priv->clk_mac_speed, rate); 1418c931b060SAnand Moon if (ret) 1419c931b060SAnand Moon dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n", 1420c931b060SAnand Moon __func__, rate, ret); 1421c931b060SAnand Moon } 1422c931b060SAnand Moon 1423c931b060SAnand Moon static const struct rk_gmac_ops rv1126_ops = { 1424c931b060SAnand Moon .set_to_rgmii = rv1126_set_to_rgmii, 1425c931b060SAnand Moon .set_to_rmii = rv1126_set_to_rmii, 1426c931b060SAnand Moon .set_rgmii_speed = rv1126_set_rgmii_speed, 1427c931b060SAnand Moon .set_rmii_speed = rv1126_set_rmii_speed, 1428c931b060SAnand Moon }; 1429c931b060SAnand Moon 1430fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON0 0xb00 1431fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON1 0xb04 1432fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON2 0xb08 1433fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON3 0xb0c 1434fecd4d7eSDavid Wu 1435fecd4d7eSDavid Wu #define RK_MACPHY_ENABLE GRF_BIT(0) 1436fecd4d7eSDavid Wu #define RK_MACPHY_DISABLE GRF_CLR_BIT(0) 1437fecd4d7eSDavid Wu #define RK_MACPHY_CFG_CLK_50M GRF_BIT(14) 1438fecd4d7eSDavid Wu #define RK_GMAC2PHY_RMII_MODE (GRF_BIT(6) | GRF_CLR_BIT(7)) 1439fecd4d7eSDavid Wu #define RK_GRF_CON2_MACPHY_ID HIWORD_UPDATE(0x1234, 0xffff, 0) 1440fecd4d7eSDavid Wu #define RK_GRF_CON3_MACPHY_ID HIWORD_UPDATE(0x35, 0x3f, 0) 1441fecd4d7eSDavid Wu 1442fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerup(struct rk_priv_data *priv) 14437ad269eaSRoger Chen { 1444fecd4d7eSDavid Wu if (priv->ops->integrated_phy_powerup) 1445fecd4d7eSDavid Wu priv->ops->integrated_phy_powerup(priv); 1446fecd4d7eSDavid Wu 1447fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M); 1448fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE); 1449fecd4d7eSDavid Wu 1450fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID); 1451fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID); 1452fecd4d7eSDavid Wu 1453fecd4d7eSDavid Wu if (priv->phy_reset) { 1454fecd4d7eSDavid Wu /* PHY needs to be disabled before trying to reset it */ 1455fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE); 1456fecd4d7eSDavid Wu if (priv->phy_reset) 1457fecd4d7eSDavid Wu reset_control_assert(priv->phy_reset); 1458fecd4d7eSDavid Wu usleep_range(10, 20); 1459fecd4d7eSDavid Wu if (priv->phy_reset) 1460fecd4d7eSDavid Wu reset_control_deassert(priv->phy_reset); 1461fecd4d7eSDavid Wu usleep_range(10, 20); 1462fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE); 1463fecd4d7eSDavid Wu msleep(30); 1464fecd4d7eSDavid Wu } 1465fecd4d7eSDavid Wu } 1466fecd4d7eSDavid Wu 1467fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerdown(struct rk_priv_data *priv) 1468fecd4d7eSDavid Wu { 1469fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE); 1470fecd4d7eSDavid Wu if (priv->phy_reset) 1471fecd4d7eSDavid Wu reset_control_assert(priv->phy_reset); 1472fecd4d7eSDavid Wu } 1473fecd4d7eSDavid Wu 1474fecd4d7eSDavid Wu static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat) 1475fecd4d7eSDavid Wu { 1476fecd4d7eSDavid Wu struct rk_priv_data *bsp_priv = plat->bsp_priv; 14777ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 1478fecd4d7eSDavid Wu int ret; 14797ad269eaSRoger Chen 14807ad269eaSRoger Chen bsp_priv->clk_enabled = false; 14817ad269eaSRoger Chen 14827ad269eaSRoger Chen bsp_priv->mac_clk_rx = devm_clk_get(dev, "mac_clk_rx"); 14837ad269eaSRoger Chen if (IS_ERR(bsp_priv->mac_clk_rx)) 1484d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1485d42202dcSRomain Perier "mac_clk_rx"); 14867ad269eaSRoger Chen 14877ad269eaSRoger Chen bsp_priv->mac_clk_tx = devm_clk_get(dev, "mac_clk_tx"); 14887ad269eaSRoger Chen if (IS_ERR(bsp_priv->mac_clk_tx)) 1489d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1490d42202dcSRomain Perier "mac_clk_tx"); 14917ad269eaSRoger Chen 14927ad269eaSRoger Chen bsp_priv->aclk_mac = devm_clk_get(dev, "aclk_mac"); 14937ad269eaSRoger Chen if (IS_ERR(bsp_priv->aclk_mac)) 1494d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1495d42202dcSRomain Perier "aclk_mac"); 14967ad269eaSRoger Chen 14977ad269eaSRoger Chen bsp_priv->pclk_mac = devm_clk_get(dev, "pclk_mac"); 14987ad269eaSRoger Chen if (IS_ERR(bsp_priv->pclk_mac)) 1499d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1500d42202dcSRomain Perier "pclk_mac"); 15017ad269eaSRoger Chen 15027ad269eaSRoger Chen bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth"); 15037ad269eaSRoger Chen if (IS_ERR(bsp_priv->clk_mac)) 1504d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1505d42202dcSRomain Perier "stmmaceth"); 15067ad269eaSRoger Chen 15077ad269eaSRoger Chen if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) { 15087ad269eaSRoger Chen bsp_priv->clk_mac_ref = devm_clk_get(dev, "clk_mac_ref"); 15097ad269eaSRoger Chen if (IS_ERR(bsp_priv->clk_mac_ref)) 1510d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1511d42202dcSRomain Perier "clk_mac_ref"); 15127ad269eaSRoger Chen 15137ad269eaSRoger Chen if (!bsp_priv->clock_input) { 15147ad269eaSRoger Chen bsp_priv->clk_mac_refout = 15157ad269eaSRoger Chen devm_clk_get(dev, "clk_mac_refout"); 15167ad269eaSRoger Chen if (IS_ERR(bsp_priv->clk_mac_refout)) 1517d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1518d42202dcSRomain Perier "clk_mac_refout"); 15197ad269eaSRoger Chen } 15207ad269eaSRoger Chen } 15217ad269eaSRoger Chen 152223c94d63SDavid Wu bsp_priv->clk_mac_speed = devm_clk_get(dev, "clk_mac_speed"); 152323c94d63SDavid Wu if (IS_ERR(bsp_priv->clk_mac_speed)) 152423c94d63SDavid Wu dev_err(dev, "cannot get clock %s\n", "clk_mac_speed"); 152523c94d63SDavid Wu 15267ad269eaSRoger Chen if (bsp_priv->clock_input) { 1527d42202dcSRomain Perier dev_info(dev, "clock input from PHY\n"); 15287ad269eaSRoger Chen } else { 15297ad269eaSRoger Chen if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) 1530c48fa33cSHeiko Stübner clk_set_rate(bsp_priv->clk_mac, 50000000); 15317ad269eaSRoger Chen } 15327ad269eaSRoger Chen 1533fecd4d7eSDavid Wu if (plat->phy_node && bsp_priv->integrated_phy) { 1534fecd4d7eSDavid Wu bsp_priv->clk_phy = of_clk_get(plat->phy_node, 0); 1535fecd4d7eSDavid Wu if (IS_ERR(bsp_priv->clk_phy)) { 1536fecd4d7eSDavid Wu ret = PTR_ERR(bsp_priv->clk_phy); 1537fecd4d7eSDavid Wu dev_err(dev, "Cannot get PHY clock: %d\n", ret); 1538fecd4d7eSDavid Wu return -EINVAL; 1539fecd4d7eSDavid Wu } 1540fecd4d7eSDavid Wu clk_set_rate(bsp_priv->clk_phy, 50000000); 1541fecd4d7eSDavid Wu } 1542fecd4d7eSDavid Wu 15437ad269eaSRoger Chen return 0; 15447ad269eaSRoger Chen } 15457ad269eaSRoger Chen 15467ad269eaSRoger Chen static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable) 15477ad269eaSRoger Chen { 1548428ad1bcSLABBE Corentin int phy_iface = bsp_priv->phy_iface; 15497ad269eaSRoger Chen 15507ad269eaSRoger Chen if (enable) { 15517ad269eaSRoger Chen if (!bsp_priv->clk_enabled) { 15527ad269eaSRoger Chen if (phy_iface == PHY_INTERFACE_MODE_RMII) { 15537ad269eaSRoger Chen if (!IS_ERR(bsp_priv->mac_clk_rx)) 15547ad269eaSRoger Chen clk_prepare_enable( 15557ad269eaSRoger Chen bsp_priv->mac_clk_rx); 15567ad269eaSRoger Chen 15577ad269eaSRoger Chen if (!IS_ERR(bsp_priv->clk_mac_ref)) 15587ad269eaSRoger Chen clk_prepare_enable( 15597ad269eaSRoger Chen bsp_priv->clk_mac_ref); 15607ad269eaSRoger Chen 15617ad269eaSRoger Chen if (!IS_ERR(bsp_priv->clk_mac_refout)) 15627ad269eaSRoger Chen clk_prepare_enable( 15637ad269eaSRoger Chen bsp_priv->clk_mac_refout); 15647ad269eaSRoger Chen } 15657ad269eaSRoger Chen 1566fecd4d7eSDavid Wu if (!IS_ERR(bsp_priv->clk_phy)) 1567fecd4d7eSDavid Wu clk_prepare_enable(bsp_priv->clk_phy); 1568fecd4d7eSDavid Wu 15697ad269eaSRoger Chen if (!IS_ERR(bsp_priv->aclk_mac)) 15707ad269eaSRoger Chen clk_prepare_enable(bsp_priv->aclk_mac); 15717ad269eaSRoger Chen 15727ad269eaSRoger Chen if (!IS_ERR(bsp_priv->pclk_mac)) 15737ad269eaSRoger Chen clk_prepare_enable(bsp_priv->pclk_mac); 15747ad269eaSRoger Chen 15757ad269eaSRoger Chen if (!IS_ERR(bsp_priv->mac_clk_tx)) 15767ad269eaSRoger Chen clk_prepare_enable(bsp_priv->mac_clk_tx); 15777ad269eaSRoger Chen 157823c94d63SDavid Wu if (!IS_ERR(bsp_priv->clk_mac_speed)) 157923c94d63SDavid Wu clk_prepare_enable(bsp_priv->clk_mac_speed); 158023c94d63SDavid Wu 15812f2b60a0SDavid Wu if (bsp_priv->ops && bsp_priv->ops->set_clock_selection) 15822f2b60a0SDavid Wu bsp_priv->ops->set_clock_selection(bsp_priv, 15832f2b60a0SDavid Wu bsp_priv->clock_input, true); 15842f2b60a0SDavid Wu 15857ad269eaSRoger Chen /** 15867ad269eaSRoger Chen * if (!IS_ERR(bsp_priv->clk_mac)) 15877ad269eaSRoger Chen * clk_prepare_enable(bsp_priv->clk_mac); 15887ad269eaSRoger Chen */ 15897ad269eaSRoger Chen mdelay(5); 15907ad269eaSRoger Chen bsp_priv->clk_enabled = true; 15917ad269eaSRoger Chen } 15927ad269eaSRoger Chen } else { 15937ad269eaSRoger Chen if (bsp_priv->clk_enabled) { 15947ad269eaSRoger Chen if (phy_iface == PHY_INTERFACE_MODE_RMII) { 159593120ebaSYueHaibing clk_disable_unprepare(bsp_priv->mac_clk_rx); 15967ad269eaSRoger Chen 159793120ebaSYueHaibing clk_disable_unprepare(bsp_priv->clk_mac_ref); 15987ad269eaSRoger Chen 159993120ebaSYueHaibing clk_disable_unprepare(bsp_priv->clk_mac_refout); 16007ad269eaSRoger Chen } 16017ad269eaSRoger Chen 1602fecd4d7eSDavid Wu clk_disable_unprepare(bsp_priv->clk_phy); 1603fecd4d7eSDavid Wu 16047ad269eaSRoger Chen clk_disable_unprepare(bsp_priv->aclk_mac); 16057ad269eaSRoger Chen 16067ad269eaSRoger Chen clk_disable_unprepare(bsp_priv->pclk_mac); 16077ad269eaSRoger Chen 16087ad269eaSRoger Chen clk_disable_unprepare(bsp_priv->mac_clk_tx); 160923c94d63SDavid Wu 161023c94d63SDavid Wu clk_disable_unprepare(bsp_priv->clk_mac_speed); 16112f2b60a0SDavid Wu 16122f2b60a0SDavid Wu if (bsp_priv->ops && bsp_priv->ops->set_clock_selection) 16132f2b60a0SDavid Wu bsp_priv->ops->set_clock_selection(bsp_priv, 16142f2b60a0SDavid Wu bsp_priv->clock_input, false); 16157ad269eaSRoger Chen /** 16167ad269eaSRoger Chen * if (!IS_ERR(bsp_priv->clk_mac)) 16177ad269eaSRoger Chen * clk_disable_unprepare(bsp_priv->clk_mac); 16187ad269eaSRoger Chen */ 16197ad269eaSRoger Chen bsp_priv->clk_enabled = false; 16207ad269eaSRoger Chen } 16217ad269eaSRoger Chen } 16227ad269eaSRoger Chen 16237ad269eaSRoger Chen return 0; 16247ad269eaSRoger Chen } 16257ad269eaSRoger Chen 16267ad269eaSRoger Chen static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable) 16277ad269eaSRoger Chen { 16282e12f536SRomain Perier struct regulator *ldo = bsp_priv->regulator; 16297ad269eaSRoger Chen int ret; 16307ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 16317ad269eaSRoger Chen 16323b25528eSChen-Yu Tsai if (!ldo) 16333b25528eSChen-Yu Tsai return 0; 16347ad269eaSRoger Chen 16357ad269eaSRoger Chen if (enable) { 16367ad269eaSRoger Chen ret = regulator_enable(ldo); 16372e12f536SRomain Perier if (ret) 1638d42202dcSRomain Perier dev_err(dev, "fail to enable phy-supply\n"); 16397ad269eaSRoger Chen } else { 16407ad269eaSRoger Chen ret = regulator_disable(ldo); 16412e12f536SRomain Perier if (ret) 1642d42202dcSRomain Perier dev_err(dev, "fail to disable phy-supply\n"); 16437ad269eaSRoger Chen } 16447ad269eaSRoger Chen 16457ad269eaSRoger Chen return 0; 16467ad269eaSRoger Chen } 16477ad269eaSRoger Chen 16480fb98db1SHeiko Stübner static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev, 1649fecd4d7eSDavid Wu struct plat_stmmacenet_data *plat, 165092c2588fSJoachim Eastwood const struct rk_gmac_ops *ops) 16517ad269eaSRoger Chen { 16527ad269eaSRoger Chen struct rk_priv_data *bsp_priv; 16537ad269eaSRoger Chen struct device *dev = &pdev->dev; 16543bb3d6b1SDavid Wu struct resource *res; 16557ad269eaSRoger Chen int ret; 16567ad269eaSRoger Chen const char *strings = NULL; 16577ad269eaSRoger Chen int value; 16587ad269eaSRoger Chen 16597ad269eaSRoger Chen bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL); 16607ad269eaSRoger Chen if (!bsp_priv) 16617ad269eaSRoger Chen return ERR_PTR(-ENOMEM); 16627ad269eaSRoger Chen 16630c65b2b9SAndrew Lunn of_get_phy_mode(dev->of_node, &bsp_priv->phy_iface); 16640fb98db1SHeiko Stübner bsp_priv->ops = ops; 16657ad269eaSRoger Chen 16663bb3d6b1SDavid Wu /* Some SoCs have multiple MAC controllers, which need 16673bb3d6b1SDavid Wu * to be distinguished. 16683bb3d6b1SDavid Wu */ 16693bb3d6b1SDavid Wu res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 16700546b224SJohn Keeping if (res && ops->regs_valid) { 16713bb3d6b1SDavid Wu int i = 0; 16723bb3d6b1SDavid Wu 16733bb3d6b1SDavid Wu while (ops->regs[i]) { 16743bb3d6b1SDavid Wu if (ops->regs[i] == res->start) { 16753bb3d6b1SDavid Wu bsp_priv->id = i; 16763bb3d6b1SDavid Wu break; 16773bb3d6b1SDavid Wu } 16783bb3d6b1SDavid Wu i++; 16793bb3d6b1SDavid Wu } 16803bb3d6b1SDavid Wu } 16813bb3d6b1SDavid Wu 16822e12f536SRomain Perier bsp_priv->regulator = devm_regulator_get_optional(dev, "phy"); 16832e12f536SRomain Perier if (IS_ERR(bsp_priv->regulator)) { 16842e12f536SRomain Perier if (PTR_ERR(bsp_priv->regulator) == -EPROBE_DEFER) { 16852e12f536SRomain Perier dev_err(dev, "phy regulator is not available yet, deferred probing\n"); 16862e12f536SRomain Perier return ERR_PTR(-EPROBE_DEFER); 16872e12f536SRomain Perier } 16882e12f536SRomain Perier dev_err(dev, "no regulator found\n"); 16892e12f536SRomain Perier bsp_priv->regulator = NULL; 16907ad269eaSRoger Chen } 16917ad269eaSRoger Chen 16927ad269eaSRoger Chen ret = of_property_read_string(dev->of_node, "clock_in_out", &strings); 16937ad269eaSRoger Chen if (ret) { 1694d42202dcSRomain Perier dev_err(dev, "Can not read property: clock_in_out.\n"); 16957ad269eaSRoger Chen bsp_priv->clock_input = true; 16967ad269eaSRoger Chen } else { 1697d42202dcSRomain Perier dev_info(dev, "clock input or output? (%s).\n", 1698d42202dcSRomain Perier strings); 16997ad269eaSRoger Chen if (!strcmp(strings, "input")) 17007ad269eaSRoger Chen bsp_priv->clock_input = true; 17017ad269eaSRoger Chen else 17027ad269eaSRoger Chen bsp_priv->clock_input = false; 17037ad269eaSRoger Chen } 17047ad269eaSRoger Chen 17057ad269eaSRoger Chen ret = of_property_read_u32(dev->of_node, "tx_delay", &value); 17067ad269eaSRoger Chen if (ret) { 17077ad269eaSRoger Chen bsp_priv->tx_delay = 0x30; 1708d42202dcSRomain Perier dev_err(dev, "Can not read property: tx_delay."); 1709d42202dcSRomain Perier dev_err(dev, "set tx_delay to 0x%x\n", 1710d42202dcSRomain Perier bsp_priv->tx_delay); 17117ad269eaSRoger Chen } else { 1712d42202dcSRomain Perier dev_info(dev, "TX delay(0x%x).\n", value); 17137ad269eaSRoger Chen bsp_priv->tx_delay = value; 17147ad269eaSRoger Chen } 17157ad269eaSRoger Chen 17167ad269eaSRoger Chen ret = of_property_read_u32(dev->of_node, "rx_delay", &value); 17177ad269eaSRoger Chen if (ret) { 17187ad269eaSRoger Chen bsp_priv->rx_delay = 0x10; 1719d42202dcSRomain Perier dev_err(dev, "Can not read property: rx_delay."); 1720d42202dcSRomain Perier dev_err(dev, "set rx_delay to 0x%x\n", 1721d42202dcSRomain Perier bsp_priv->rx_delay); 17227ad269eaSRoger Chen } else { 1723d42202dcSRomain Perier dev_info(dev, "RX delay(0x%x).\n", value); 17247ad269eaSRoger Chen bsp_priv->rx_delay = value; 17257ad269eaSRoger Chen } 17267ad269eaSRoger Chen 17277ad269eaSRoger Chen bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node, 17287ad269eaSRoger Chen "rockchip,grf"); 17292f2b60a0SDavid Wu bsp_priv->php_grf = syscon_regmap_lookup_by_phandle(dev->of_node, 17302f2b60a0SDavid Wu "rockchip,php-grf"); 17317ad269eaSRoger Chen 1732fecd4d7eSDavid Wu if (plat->phy_node) { 1733fecd4d7eSDavid Wu bsp_priv->integrated_phy = of_property_read_bool(plat->phy_node, 1734fecd4d7eSDavid Wu "phy-is-integrated"); 1735fecd4d7eSDavid Wu if (bsp_priv->integrated_phy) { 1736fecd4d7eSDavid Wu bsp_priv->phy_reset = of_reset_control_get(plat->phy_node, NULL); 1737fecd4d7eSDavid Wu if (IS_ERR(bsp_priv->phy_reset)) { 1738fecd4d7eSDavid Wu dev_err(&pdev->dev, "No PHY reset control found.\n"); 1739fecd4d7eSDavid Wu bsp_priv->phy_reset = NULL; 1740fecd4d7eSDavid Wu } 1741fecd4d7eSDavid Wu } 1742fecd4d7eSDavid Wu } 1743fecd4d7eSDavid Wu dev_info(dev, "integrated PHY? (%s).\n", 1744fecd4d7eSDavid Wu bsp_priv->integrated_phy ? "yes" : "no"); 1745fecd4d7eSDavid Wu 1746fecd4d7eSDavid Wu bsp_priv->pdev = pdev; 174745383f52SRoger Chen 174845383f52SRoger Chen return bsp_priv; 174945383f52SRoger Chen } 175045383f52SRoger Chen 175137c80d15SDavid Wu static int rk_gmac_check_ops(struct rk_priv_data *bsp_priv) 175237c80d15SDavid Wu { 175337c80d15SDavid Wu switch (bsp_priv->phy_iface) { 175437c80d15SDavid Wu case PHY_INTERFACE_MODE_RGMII: 175537c80d15SDavid Wu case PHY_INTERFACE_MODE_RGMII_ID: 175637c80d15SDavid Wu case PHY_INTERFACE_MODE_RGMII_RXID: 175737c80d15SDavid Wu case PHY_INTERFACE_MODE_RGMII_TXID: 175837c80d15SDavid Wu if (!bsp_priv->ops->set_to_rgmii) 175937c80d15SDavid Wu return -EINVAL; 176037c80d15SDavid Wu break; 176137c80d15SDavid Wu case PHY_INTERFACE_MODE_RMII: 176237c80d15SDavid Wu if (!bsp_priv->ops->set_to_rmii) 176337c80d15SDavid Wu return -EINVAL; 176437c80d15SDavid Wu break; 176537c80d15SDavid Wu default: 176637c80d15SDavid Wu dev_err(&bsp_priv->pdev->dev, 176737c80d15SDavid Wu "unsupported interface %d", bsp_priv->phy_iface); 176837c80d15SDavid Wu } 176937c80d15SDavid Wu return 0; 177037c80d15SDavid Wu } 177137c80d15SDavid Wu 177245383f52SRoger Chen static int rk_gmac_powerup(struct rk_priv_data *bsp_priv) 177345383f52SRoger Chen { 177445383f52SRoger Chen int ret; 177545383f52SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 177645383f52SRoger Chen 177737c80d15SDavid Wu ret = rk_gmac_check_ops(bsp_priv); 177837c80d15SDavid Wu if (ret) 177937c80d15SDavid Wu return ret; 178037c80d15SDavid Wu 1781f217bfdeSHeiko Stübner ret = gmac_clk_enable(bsp_priv, true); 1782f217bfdeSHeiko Stübner if (ret) 1783f217bfdeSHeiko Stübner return ret; 1784f217bfdeSHeiko Stübner 17857ad269eaSRoger Chen /*rmii or rgmii*/ 1786eaf70ad1SWadim Egorov switch (bsp_priv->phy_iface) { 1787eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII: 1788d42202dcSRomain Perier dev_info(dev, "init for RGMII\n"); 17890fb98db1SHeiko Stübner bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 17900fb98db1SHeiko Stübner bsp_priv->rx_delay); 1791eaf70ad1SWadim Egorov break; 1792eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_ID: 1793eaf70ad1SWadim Egorov dev_info(dev, "init for RGMII_ID\n"); 1794eaf70ad1SWadim Egorov bsp_priv->ops->set_to_rgmii(bsp_priv, 0, 0); 1795eaf70ad1SWadim Egorov break; 1796eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_RXID: 1797eaf70ad1SWadim Egorov dev_info(dev, "init for RGMII_RXID\n"); 1798eaf70ad1SWadim Egorov bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 0); 1799eaf70ad1SWadim Egorov break; 1800eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_TXID: 1801eaf70ad1SWadim Egorov dev_info(dev, "init for RGMII_TXID\n"); 1802eaf70ad1SWadim Egorov bsp_priv->ops->set_to_rgmii(bsp_priv, 0, bsp_priv->rx_delay); 1803eaf70ad1SWadim Egorov break; 1804eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RMII: 1805d42202dcSRomain Perier dev_info(dev, "init for RMII\n"); 18060fb98db1SHeiko Stübner bsp_priv->ops->set_to_rmii(bsp_priv); 1807eaf70ad1SWadim Egorov break; 1808eaf70ad1SWadim Egorov default: 1809d42202dcSRomain Perier dev_err(dev, "NO interface defined!\n"); 18107ad269eaSRoger Chen } 18117ad269eaSRoger Chen 18127ad269eaSRoger Chen ret = phy_power_on(bsp_priv, true); 1813c69c29a1SAlexey Khoroshilov if (ret) { 1814c69c29a1SAlexey Khoroshilov gmac_clk_enable(bsp_priv, false); 18157ad269eaSRoger Chen return ret; 1816c69c29a1SAlexey Khoroshilov } 18177ad269eaSRoger Chen 1818aec3f415SPunit Agrawal pm_runtime_get_sync(dev); 1819aec3f415SPunit Agrawal 1820fecd4d7eSDavid Wu if (bsp_priv->integrated_phy) 1821fecd4d7eSDavid Wu rk_gmac_integrated_phy_powerup(bsp_priv); 1822fecd4d7eSDavid Wu 18237ad269eaSRoger Chen return 0; 18247ad269eaSRoger Chen } 18257ad269eaSRoger Chen 1826229666c1SVincent Palatin static void rk_gmac_powerdown(struct rk_priv_data *gmac) 18277ad269eaSRoger Chen { 1828fecd4d7eSDavid Wu if (gmac->integrated_phy) 1829fecd4d7eSDavid Wu rk_gmac_integrated_phy_powerdown(gmac); 1830fecd4d7eSDavid Wu 1831aec3f415SPunit Agrawal pm_runtime_put_sync(&gmac->pdev->dev); 1832aec3f415SPunit Agrawal 18337ad269eaSRoger Chen phy_power_on(gmac, false); 18347ad269eaSRoger Chen gmac_clk_enable(gmac, false); 18357ad269eaSRoger Chen } 18367ad269eaSRoger Chen 18377ad269eaSRoger Chen static void rk_fix_speed(void *priv, unsigned int speed) 18387ad269eaSRoger Chen { 18397ad269eaSRoger Chen struct rk_priv_data *bsp_priv = priv; 18407ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 18417ad269eaSRoger Chen 1842eaf70ad1SWadim Egorov switch (bsp_priv->phy_iface) { 1843eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII: 1844eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_ID: 1845eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_RXID: 1846eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_TXID: 184737c80d15SDavid Wu if (bsp_priv->ops->set_rgmii_speed) 18480fb98db1SHeiko Stübner bsp_priv->ops->set_rgmii_speed(bsp_priv, speed); 1849eaf70ad1SWadim Egorov break; 1850eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RMII: 185137c80d15SDavid Wu if (bsp_priv->ops->set_rmii_speed) 18520fb98db1SHeiko Stübner bsp_priv->ops->set_rmii_speed(bsp_priv, speed); 1853eaf70ad1SWadim Egorov break; 1854eaf70ad1SWadim Egorov default: 18557ad269eaSRoger Chen dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface); 18567ad269eaSRoger Chen } 1857eaf70ad1SWadim Egorov } 18587ad269eaSRoger Chen 185927ffefd2SJoachim Eastwood static int rk_gmac_probe(struct platform_device *pdev) 186027ffefd2SJoachim Eastwood { 186127ffefd2SJoachim Eastwood struct plat_stmmacenet_data *plat_dat; 186227ffefd2SJoachim Eastwood struct stmmac_resources stmmac_res; 1863f529f182SJoachim Eastwood const struct rk_gmac_ops *data; 186427ffefd2SJoachim Eastwood int ret; 186527ffefd2SJoachim Eastwood 1866149adeddSJoachim Eastwood data = of_device_get_match_data(&pdev->dev); 1867149adeddSJoachim Eastwood if (!data) { 1868149adeddSJoachim Eastwood dev_err(&pdev->dev, "no of match data provided\n"); 1869149adeddSJoachim Eastwood return -EINVAL; 1870149adeddSJoachim Eastwood } 1871149adeddSJoachim Eastwood 187227ffefd2SJoachim Eastwood ret = stmmac_get_platform_resources(pdev, &stmmac_res); 187327ffefd2SJoachim Eastwood if (ret) 187427ffefd2SJoachim Eastwood return ret; 187527ffefd2SJoachim Eastwood 187683216e39SMichael Walle plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac); 187727ffefd2SJoachim Eastwood if (IS_ERR(plat_dat)) 187827ffefd2SJoachim Eastwood return PTR_ERR(plat_dat); 187927ffefd2SJoachim Eastwood 1880d6b06251SEzequiel Garcia /* If the stmmac is not already selected as gmac4, 1881d6b06251SEzequiel Garcia * then make sure we fallback to gmac. 1882d6b06251SEzequiel Garcia */ 1883d6b06251SEzequiel Garcia if (!plat_dat->has_gmac4) 188427ffefd2SJoachim Eastwood plat_dat->has_gmac = true; 188527ffefd2SJoachim Eastwood plat_dat->fix_mac_speed = rk_fix_speed; 188627ffefd2SJoachim Eastwood 1887fecd4d7eSDavid Wu plat_dat->bsp_priv = rk_gmac_setup(pdev, plat_dat, data); 1888d2ed0a77SJohan Hovold if (IS_ERR(plat_dat->bsp_priv)) { 1889d2ed0a77SJohan Hovold ret = PTR_ERR(plat_dat->bsp_priv); 1890d2ed0a77SJohan Hovold goto err_remove_config_dt; 1891d2ed0a77SJohan Hovold } 189227ffefd2SJoachim Eastwood 1893fecd4d7eSDavid Wu ret = rk_gmac_clk_init(plat_dat); 1894fecd4d7eSDavid Wu if (ret) 18959de9aa48SEmil Renner Berthing goto err_remove_config_dt; 1896fecd4d7eSDavid Wu 189707a5e769SJoachim Eastwood ret = rk_gmac_powerup(plat_dat->bsp_priv); 189827ffefd2SJoachim Eastwood if (ret) 1899d2ed0a77SJohan Hovold goto err_remove_config_dt; 190027ffefd2SJoachim Eastwood 19012d222656SJohan Hovold ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); 19022d222656SJohan Hovold if (ret) 19032745529aSDavid S. Miller goto err_gmac_powerdown; 19042d222656SJohan Hovold 19052d222656SJohan Hovold return 0; 19062d222656SJohan Hovold 19072745529aSDavid S. Miller err_gmac_powerdown: 19082745529aSDavid S. Miller rk_gmac_powerdown(plat_dat->bsp_priv); 1909d2ed0a77SJohan Hovold err_remove_config_dt: 1910d2ed0a77SJohan Hovold stmmac_remove_config_dt(pdev, plat_dat); 19112d222656SJohan Hovold 19122d222656SJohan Hovold return ret; 191327ffefd2SJoachim Eastwood } 191427ffefd2SJoachim Eastwood 19150de8c4c9SJoachim Eastwood static int rk_gmac_remove(struct platform_device *pdev) 19160de8c4c9SJoachim Eastwood { 19170de8c4c9SJoachim Eastwood struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(&pdev->dev); 1918*ff0011cfSUwe Kleine-König 1919*ff0011cfSUwe Kleine-König stmmac_dvr_remove(&pdev->dev); 19200de8c4c9SJoachim Eastwood 19210de8c4c9SJoachim Eastwood rk_gmac_powerdown(bsp_priv); 19220de8c4c9SJoachim Eastwood 1923*ff0011cfSUwe Kleine-König return 0; 19240de8c4c9SJoachim Eastwood } 19250de8c4c9SJoachim Eastwood 19265619468aSJoachim Eastwood #ifdef CONFIG_PM_SLEEP 19275619468aSJoachim Eastwood static int rk_gmac_suspend(struct device *dev) 19285619468aSJoachim Eastwood { 19295619468aSJoachim Eastwood struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev); 19305619468aSJoachim Eastwood int ret = stmmac_suspend(dev); 19315619468aSJoachim Eastwood 19325619468aSJoachim Eastwood /* Keep the PHY up if we use Wake-on-Lan. */ 19335619468aSJoachim Eastwood if (!device_may_wakeup(dev)) { 19345619468aSJoachim Eastwood rk_gmac_powerdown(bsp_priv); 19355619468aSJoachim Eastwood bsp_priv->suspended = true; 19365619468aSJoachim Eastwood } 19375619468aSJoachim Eastwood 19385619468aSJoachim Eastwood return ret; 19395619468aSJoachim Eastwood } 19405619468aSJoachim Eastwood 19415619468aSJoachim Eastwood static int rk_gmac_resume(struct device *dev) 19425619468aSJoachim Eastwood { 19435619468aSJoachim Eastwood struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev); 19445619468aSJoachim Eastwood 19455619468aSJoachim Eastwood /* The PHY was up for Wake-on-Lan. */ 19465619468aSJoachim Eastwood if (bsp_priv->suspended) { 19475619468aSJoachim Eastwood rk_gmac_powerup(bsp_priv); 19485619468aSJoachim Eastwood bsp_priv->suspended = false; 19495619468aSJoachim Eastwood } 19505619468aSJoachim Eastwood 19515619468aSJoachim Eastwood return stmmac_resume(dev); 19525619468aSJoachim Eastwood } 19535619468aSJoachim Eastwood #endif /* CONFIG_PM_SLEEP */ 19545619468aSJoachim Eastwood 19555619468aSJoachim Eastwood static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume); 19565619468aSJoachim Eastwood 1957e0fb4013SJoachim Eastwood static const struct of_device_id rk_gmac_dwmac_match[] = { 195823c94d63SDavid Wu { .compatible = "rockchip,px30-gmac", .data = &px30_ops }, 195905946876SDavid Wu { .compatible = "rockchip,rk3128-gmac", .data = &rk3128_ops }, 1960e7ffd812SXing Zheng { .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops }, 1961f529f182SJoachim Eastwood { .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops }, 1962b4ac9456STobias Schramm { .compatible = "rockchip,rk3308-gmac", .data = &rk3308_ops }, 1963d4ff816eSdavid.wu { .compatible = "rockchip,rk3328-gmac", .data = &rk3328_ops }, 1964ba289af8SRoger Chen { .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops }, 1965f529f182SJoachim Eastwood { .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops }, 1966ba289af8SRoger Chen { .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops }, 19673bb3d6b1SDavid Wu { .compatible = "rockchip,rk3568-gmac", .data = &rk3568_ops }, 19682f2b60a0SDavid Wu { .compatible = "rockchip,rk3588-gmac", .data = &rk3588_ops }, 196989c9c163SDavid Wu { .compatible = "rockchip,rv1108-gmac", .data = &rv1108_ops }, 1970c931b060SAnand Moon { .compatible = "rockchip,rv1126-gmac", .data = &rv1126_ops }, 1971e0fb4013SJoachim Eastwood { } 1972e0fb4013SJoachim Eastwood }; 1973e0fb4013SJoachim Eastwood MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match); 1974e0fb4013SJoachim Eastwood 1975e0fb4013SJoachim Eastwood static struct platform_driver rk_gmac_dwmac_driver = { 197627ffefd2SJoachim Eastwood .probe = rk_gmac_probe, 19770de8c4c9SJoachim Eastwood .remove = rk_gmac_remove, 1978e0fb4013SJoachim Eastwood .driver = { 1979e0fb4013SJoachim Eastwood .name = "rk_gmac-dwmac", 19805619468aSJoachim Eastwood .pm = &rk_gmac_pm_ops, 1981e0fb4013SJoachim Eastwood .of_match_table = rk_gmac_dwmac_match, 1982e0fb4013SJoachim Eastwood }, 1983e0fb4013SJoachim Eastwood }; 1984e0fb4013SJoachim Eastwood module_platform_driver(rk_gmac_dwmac_driver); 1985e0fb4013SJoachim Eastwood 1986e0fb4013SJoachim Eastwood MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>"); 1987e0fb4013SJoachim Eastwood MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer"); 1988e0fb4013SJoachim Eastwood MODULE_LICENSE("GPL"); 1989