1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 27ad269eaSRoger Chen /** 37ad269eaSRoger Chen * 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> 242c896fb0SDavid Wu #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); 35fecd4d7eSDavid Wu void (*integrated_phy_powerup)(struct rk_priv_data *bsp_priv); 360fb98db1SHeiko Stübner }; 370fb98db1SHeiko Stübner 387ad269eaSRoger Chen struct rk_priv_data { 397ad269eaSRoger Chen struct platform_device *pdev; 400c65b2b9SAndrew Lunn phy_interface_t phy_iface; 412e12f536SRomain Perier struct regulator *regulator; 42229666c1SVincent Palatin bool suspended; 4392c2588fSJoachim Eastwood const struct rk_gmac_ops *ops; 447ad269eaSRoger Chen 457ad269eaSRoger Chen bool clk_enabled; 467ad269eaSRoger Chen bool clock_input; 47fecd4d7eSDavid Wu bool integrated_phy; 487ad269eaSRoger Chen 497ad269eaSRoger Chen struct clk *clk_mac; 507ad269eaSRoger Chen struct clk *gmac_clkin; 517ad269eaSRoger Chen struct clk *mac_clk_rx; 527ad269eaSRoger Chen struct clk *mac_clk_tx; 537ad269eaSRoger Chen struct clk *clk_mac_ref; 547ad269eaSRoger Chen struct clk *clk_mac_refout; 5523c94d63SDavid Wu struct clk *clk_mac_speed; 567ad269eaSRoger Chen struct clk *aclk_mac; 577ad269eaSRoger Chen struct clk *pclk_mac; 58fecd4d7eSDavid Wu struct clk *clk_phy; 59fecd4d7eSDavid Wu 60fecd4d7eSDavid Wu struct reset_control *phy_reset; 617ad269eaSRoger Chen 627ad269eaSRoger Chen int tx_delay; 637ad269eaSRoger Chen int rx_delay; 647ad269eaSRoger Chen 657ad269eaSRoger Chen struct regmap *grf; 667ad269eaSRoger Chen }; 677ad269eaSRoger Chen 687ad269eaSRoger Chen #define HIWORD_UPDATE(val, mask, shift) \ 697ad269eaSRoger Chen ((val) << (shift) | (mask) << ((shift) + 16)) 707ad269eaSRoger Chen 717ad269eaSRoger Chen #define GRF_BIT(nr) (BIT(nr) | BIT(nr+16)) 727ad269eaSRoger Chen #define GRF_CLR_BIT(nr) (BIT(nr+16)) 737ad269eaSRoger Chen 74eaf70ad1SWadim Egorov #define DELAY_ENABLE(soc, tx, rx) \ 75eaf70ad1SWadim Egorov (((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \ 76eaf70ad1SWadim Egorov ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE)) 77eaf70ad1SWadim Egorov 7823c94d63SDavid Wu #define PX30_GRF_GMAC_CON1 0x0904 7923c94d63SDavid Wu 8023c94d63SDavid Wu /* PX30_GRF_GMAC_CON1 */ 8123c94d63SDavid Wu #define PX30_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \ 8223c94d63SDavid Wu GRF_BIT(6)) 8323c94d63SDavid Wu #define PX30_GMAC_SPEED_10M GRF_CLR_BIT(2) 8423c94d63SDavid Wu #define PX30_GMAC_SPEED_100M GRF_BIT(2) 8523c94d63SDavid Wu 8623c94d63SDavid Wu static void px30_set_to_rmii(struct rk_priv_data *bsp_priv) 8723c94d63SDavid Wu { 8823c94d63SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 8923c94d63SDavid Wu 9023c94d63SDavid Wu if (IS_ERR(bsp_priv->grf)) { 9123c94d63SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 9223c94d63SDavid Wu return; 9323c94d63SDavid Wu } 9423c94d63SDavid Wu 9523c94d63SDavid Wu regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1, 9623c94d63SDavid Wu PX30_GMAC_PHY_INTF_SEL_RMII); 9723c94d63SDavid Wu } 9823c94d63SDavid Wu 9923c94d63SDavid Wu static void px30_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 10023c94d63SDavid Wu { 10123c94d63SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 10223c94d63SDavid Wu int ret; 10323c94d63SDavid Wu 10423c94d63SDavid Wu if (IS_ERR(bsp_priv->clk_mac_speed)) { 10523c94d63SDavid Wu dev_err(dev, "%s: Missing clk_mac_speed clock\n", __func__); 10623c94d63SDavid Wu return; 10723c94d63SDavid Wu } 10823c94d63SDavid Wu 10923c94d63SDavid Wu if (speed == 10) { 11023c94d63SDavid Wu regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1, 11123c94d63SDavid Wu PX30_GMAC_SPEED_10M); 11223c94d63SDavid Wu 11323c94d63SDavid Wu ret = clk_set_rate(bsp_priv->clk_mac_speed, 2500000); 11423c94d63SDavid Wu if (ret) 11523c94d63SDavid Wu dev_err(dev, "%s: set clk_mac_speed rate 2500000 failed: %d\n", 11623c94d63SDavid Wu __func__, ret); 11723c94d63SDavid Wu } else if (speed == 100) { 11823c94d63SDavid Wu regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1, 11923c94d63SDavid Wu PX30_GMAC_SPEED_100M); 12023c94d63SDavid Wu 12123c94d63SDavid Wu ret = clk_set_rate(bsp_priv->clk_mac_speed, 25000000); 12223c94d63SDavid Wu if (ret) 12323c94d63SDavid Wu dev_err(dev, "%s: set clk_mac_speed rate 25000000 failed: %d\n", 12423c94d63SDavid Wu __func__, ret); 12523c94d63SDavid Wu 12623c94d63SDavid Wu } else { 12723c94d63SDavid Wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 12823c94d63SDavid Wu } 12923c94d63SDavid Wu } 13023c94d63SDavid Wu 13123c94d63SDavid Wu static const struct rk_gmac_ops px30_ops = { 13223c94d63SDavid Wu .set_to_rmii = px30_set_to_rmii, 13323c94d63SDavid Wu .set_rmii_speed = px30_set_rmii_speed, 13423c94d63SDavid Wu }; 13523c94d63SDavid Wu 13605946876SDavid Wu #define RK3128_GRF_MAC_CON0 0x0168 13705946876SDavid Wu #define RK3128_GRF_MAC_CON1 0x016c 13805946876SDavid Wu 13905946876SDavid Wu /* RK3128_GRF_MAC_CON0 */ 14005946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_ENABLE GRF_BIT(14) 14105946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14) 14205946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 14305946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 14405946876SDavid Wu #define RK3128_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 14505946876SDavid Wu #define RK3128_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 14605946876SDavid Wu 14705946876SDavid Wu /* RK3128_GRF_MAC_CON1 */ 14805946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RGMII \ 14905946876SDavid Wu (GRF_BIT(6) | GRF_CLR_BIT(7) | GRF_CLR_BIT(8)) 15005946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RMII \ 15105946876SDavid Wu (GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | GRF_BIT(8)) 15205946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL GRF_BIT(9) 15305946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(9) 15405946876SDavid Wu #define RK3128_GMAC_SPEED_10M GRF_CLR_BIT(10) 15505946876SDavid Wu #define RK3128_GMAC_SPEED_100M GRF_BIT(10) 15605946876SDavid Wu #define RK3128_GMAC_RMII_CLK_25M GRF_BIT(11) 15705946876SDavid Wu #define RK3128_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(11) 15805946876SDavid Wu #define RK3128_GMAC_CLK_125M (GRF_CLR_BIT(12) | GRF_CLR_BIT(13)) 15905946876SDavid Wu #define RK3128_GMAC_CLK_25M (GRF_BIT(12) | GRF_BIT(13)) 16005946876SDavid Wu #define RK3128_GMAC_CLK_2_5M (GRF_CLR_BIT(12) | GRF_BIT(13)) 16105946876SDavid Wu #define RK3128_GMAC_RMII_MODE GRF_BIT(14) 16205946876SDavid Wu #define RK3128_GMAC_RMII_MODE_CLR GRF_CLR_BIT(14) 16305946876SDavid Wu 16405946876SDavid Wu static void rk3128_set_to_rgmii(struct rk_priv_data *bsp_priv, 16505946876SDavid Wu int tx_delay, int rx_delay) 16605946876SDavid Wu { 16705946876SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 16805946876SDavid Wu 16905946876SDavid Wu if (IS_ERR(bsp_priv->grf)) { 17005946876SDavid Wu dev_err(dev, "Missing rockchip,grf property\n"); 17105946876SDavid Wu return; 17205946876SDavid Wu } 17305946876SDavid Wu 17405946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 17505946876SDavid Wu RK3128_GMAC_PHY_INTF_SEL_RGMII | 17605946876SDavid Wu RK3128_GMAC_RMII_MODE_CLR); 17705946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON0, 17805946876SDavid Wu DELAY_ENABLE(RK3128, tx_delay, rx_delay) | 17905946876SDavid Wu RK3128_GMAC_CLK_RX_DL_CFG(rx_delay) | 18005946876SDavid Wu RK3128_GMAC_CLK_TX_DL_CFG(tx_delay)); 18105946876SDavid Wu } 18205946876SDavid Wu 18305946876SDavid Wu static void rk3128_set_to_rmii(struct rk_priv_data *bsp_priv) 18405946876SDavid Wu { 18505946876SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 18605946876SDavid Wu 18705946876SDavid Wu if (IS_ERR(bsp_priv->grf)) { 18805946876SDavid Wu dev_err(dev, "Missing rockchip,grf property\n"); 18905946876SDavid Wu return; 19005946876SDavid Wu } 19105946876SDavid Wu 19205946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 19305946876SDavid Wu RK3128_GMAC_PHY_INTF_SEL_RMII | RK3128_GMAC_RMII_MODE); 19405946876SDavid Wu } 19505946876SDavid Wu 19605946876SDavid Wu static void rk3128_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 19705946876SDavid Wu { 19805946876SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 19905946876SDavid Wu 20005946876SDavid Wu if (IS_ERR(bsp_priv->grf)) { 20105946876SDavid Wu dev_err(dev, "Missing rockchip,grf property\n"); 20205946876SDavid Wu return; 20305946876SDavid Wu } 20405946876SDavid Wu 20505946876SDavid Wu if (speed == 10) 20605946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 20705946876SDavid Wu RK3128_GMAC_CLK_2_5M); 20805946876SDavid Wu else if (speed == 100) 20905946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 21005946876SDavid Wu RK3128_GMAC_CLK_25M); 21105946876SDavid Wu else if (speed == 1000) 21205946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 21305946876SDavid Wu RK3128_GMAC_CLK_125M); 21405946876SDavid Wu else 21505946876SDavid Wu dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 21605946876SDavid Wu } 21705946876SDavid Wu 21805946876SDavid Wu static void rk3128_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 21905946876SDavid Wu { 22005946876SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 22105946876SDavid Wu 22205946876SDavid Wu if (IS_ERR(bsp_priv->grf)) { 22305946876SDavid Wu dev_err(dev, "Missing rockchip,grf property\n"); 22405946876SDavid Wu return; 22505946876SDavid Wu } 22605946876SDavid Wu 22705946876SDavid Wu if (speed == 10) { 22805946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 22905946876SDavid Wu RK3128_GMAC_RMII_CLK_2_5M | 23005946876SDavid Wu RK3128_GMAC_SPEED_10M); 23105946876SDavid Wu } else if (speed == 100) { 23205946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 23305946876SDavid Wu RK3128_GMAC_RMII_CLK_25M | 23405946876SDavid Wu RK3128_GMAC_SPEED_100M); 23505946876SDavid Wu } else { 23605946876SDavid Wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 23705946876SDavid Wu } 23805946876SDavid Wu } 23905946876SDavid Wu 24005946876SDavid Wu static const struct rk_gmac_ops rk3128_ops = { 24105946876SDavid Wu .set_to_rgmii = rk3128_set_to_rgmii, 24205946876SDavid Wu .set_to_rmii = rk3128_set_to_rmii, 24305946876SDavid Wu .set_rgmii_speed = rk3128_set_rgmii_speed, 24405946876SDavid Wu .set_rmii_speed = rk3128_set_rmii_speed, 24505946876SDavid Wu }; 24605946876SDavid Wu 247e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON0 0x0900 248e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON1 0x0904 249e7ffd812SXing Zheng 2506fa12c78SDavid Wu #define RK3228_GRF_CON_MUX 0x50 2516fa12c78SDavid Wu 252e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON0 */ 253e7ffd812SXing Zheng #define RK3228_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 254e7ffd812SXing Zheng #define RK3228_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 255e7ffd812SXing Zheng 256e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON1 */ 257e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RGMII \ 258e7ffd812SXing Zheng (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6)) 259e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RMII \ 260e7ffd812SXing Zheng (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6)) 261e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL GRF_BIT(3) 262e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 263e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_10M GRF_CLR_BIT(2) 264e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_100M GRF_BIT(2) 265e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_25M GRF_BIT(7) 266e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7) 267e7ffd812SXing Zheng #define RK3228_GMAC_CLK_125M (GRF_CLR_BIT(8) | GRF_CLR_BIT(9)) 268e7ffd812SXing Zheng #define RK3228_GMAC_CLK_25M (GRF_BIT(8) | GRF_BIT(9)) 269e7ffd812SXing Zheng #define RK3228_GMAC_CLK_2_5M (GRF_CLR_BIT(8) | GRF_BIT(9)) 270e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE GRF_BIT(10) 271e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE_CLR GRF_CLR_BIT(10) 272e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0) 273e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0) 274e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1) 275e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(1) 276e7ffd812SXing Zheng 2776fa12c78SDavid Wu /* RK3228_GRF_COM_MUX */ 2786fa12c78SDavid Wu #define RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY GRF_BIT(15) 2796fa12c78SDavid Wu 280e7ffd812SXing Zheng static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv, 281e7ffd812SXing Zheng int tx_delay, int rx_delay) 282e7ffd812SXing Zheng { 283e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 284e7ffd812SXing Zheng 285e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 286e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 287e7ffd812SXing Zheng return; 288e7ffd812SXing Zheng } 289e7ffd812SXing Zheng 290e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 291e7ffd812SXing Zheng RK3228_GMAC_PHY_INTF_SEL_RGMII | 292e7ffd812SXing Zheng RK3228_GMAC_RMII_MODE_CLR | 293eaf70ad1SWadim Egorov DELAY_ENABLE(RK3228, tx_delay, rx_delay)); 294e7ffd812SXing Zheng 295e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON0, 296e7ffd812SXing Zheng RK3228_GMAC_CLK_RX_DL_CFG(rx_delay) | 297e7ffd812SXing Zheng RK3228_GMAC_CLK_TX_DL_CFG(tx_delay)); 298e7ffd812SXing Zheng } 299e7ffd812SXing Zheng 300e7ffd812SXing Zheng static void rk3228_set_to_rmii(struct rk_priv_data *bsp_priv) 301e7ffd812SXing Zheng { 302e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 303e7ffd812SXing Zheng 304e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 305e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 306e7ffd812SXing Zheng return; 307e7ffd812SXing Zheng } 308e7ffd812SXing Zheng 309e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 310e7ffd812SXing Zheng RK3228_GMAC_PHY_INTF_SEL_RMII | 311e7ffd812SXing Zheng RK3228_GMAC_RMII_MODE); 312e7ffd812SXing Zheng 313e7ffd812SXing Zheng /* set MAC to RMII mode */ 314e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, GRF_BIT(11)); 315e7ffd812SXing Zheng } 316e7ffd812SXing Zheng 317e7ffd812SXing Zheng static void rk3228_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 318e7ffd812SXing Zheng { 319e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 320e7ffd812SXing Zheng 321e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 322e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 323e7ffd812SXing Zheng return; 324e7ffd812SXing Zheng } 325e7ffd812SXing Zheng 326e7ffd812SXing Zheng if (speed == 10) 327e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 328e7ffd812SXing Zheng RK3228_GMAC_CLK_2_5M); 329e7ffd812SXing Zheng else if (speed == 100) 330e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 331e7ffd812SXing Zheng RK3228_GMAC_CLK_25M); 332e7ffd812SXing Zheng else if (speed == 1000) 333e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 334e7ffd812SXing Zheng RK3228_GMAC_CLK_125M); 335e7ffd812SXing Zheng else 336e7ffd812SXing Zheng dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 337e7ffd812SXing Zheng } 338e7ffd812SXing Zheng 339e7ffd812SXing Zheng static void rk3228_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 340e7ffd812SXing Zheng { 341e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 342e7ffd812SXing Zheng 343e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 344e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 345e7ffd812SXing Zheng return; 346e7ffd812SXing Zheng } 347e7ffd812SXing Zheng 348e7ffd812SXing Zheng if (speed == 10) 349e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 350e7ffd812SXing Zheng RK3228_GMAC_RMII_CLK_2_5M | 351e7ffd812SXing Zheng RK3228_GMAC_SPEED_10M); 352e7ffd812SXing Zheng else if (speed == 100) 353e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 354e7ffd812SXing Zheng RK3228_GMAC_RMII_CLK_25M | 355e7ffd812SXing Zheng RK3228_GMAC_SPEED_100M); 356e7ffd812SXing Zheng else 357e7ffd812SXing Zheng dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 358e7ffd812SXing Zheng } 359e7ffd812SXing Zheng 3606fa12c78SDavid Wu static void rk3228_integrated_phy_powerup(struct rk_priv_data *priv) 3616fa12c78SDavid Wu { 3626fa12c78SDavid Wu regmap_write(priv->grf, RK3228_GRF_CON_MUX, 3636fa12c78SDavid Wu RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY); 3646fa12c78SDavid Wu } 3656fa12c78SDavid Wu 366e7ffd812SXing Zheng static const struct rk_gmac_ops rk3228_ops = { 367e7ffd812SXing Zheng .set_to_rgmii = rk3228_set_to_rgmii, 368e7ffd812SXing Zheng .set_to_rmii = rk3228_set_to_rmii, 369e7ffd812SXing Zheng .set_rgmii_speed = rk3228_set_rgmii_speed, 370e7ffd812SXing Zheng .set_rmii_speed = rk3228_set_rmii_speed, 3716fa12c78SDavid Wu .integrated_phy_powerup = rk3228_integrated_phy_powerup, 372e7ffd812SXing Zheng }; 373e7ffd812SXing Zheng 3747ad269eaSRoger Chen #define RK3288_GRF_SOC_CON1 0x0248 3757ad269eaSRoger Chen #define RK3288_GRF_SOC_CON3 0x0250 3767ad269eaSRoger Chen 3777ad269eaSRoger Chen /*RK3288_GRF_SOC_CON1*/ 3780fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(6) | GRF_CLR_BIT(7) | \ 3790fb98db1SHeiko Stübner GRF_CLR_BIT(8)) 3800fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | \ 3810fb98db1SHeiko Stübner GRF_BIT(8)) 3820fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL GRF_BIT(9) 3830fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(9) 3840fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_10M GRF_CLR_BIT(10) 3850fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_100M GRF_BIT(10) 3860fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_25M GRF_BIT(11) 3870fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(11) 3880fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_125M (GRF_CLR_BIT(12) | GRF_CLR_BIT(13)) 3890fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_25M (GRF_BIT(12) | GRF_BIT(13)) 3900fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_2_5M (GRF_CLR_BIT(12) | GRF_BIT(13)) 3910fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE GRF_BIT(14) 3920fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE_CLR GRF_CLR_BIT(14) 3937ad269eaSRoger Chen 3947ad269eaSRoger Chen /*RK3288_GRF_SOC_CON3*/ 3950fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_ENABLE GRF_BIT(14) 3960fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14) 3970fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 3980fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 3990fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 4000fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 4017ad269eaSRoger Chen 4020fb98db1SHeiko Stübner static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv, 4037ad269eaSRoger Chen int tx_delay, int rx_delay) 4047ad269eaSRoger Chen { 4057ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 4067ad269eaSRoger Chen 4077ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 408d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 4097ad269eaSRoger Chen return; 4107ad269eaSRoger Chen } 4117ad269eaSRoger Chen 4127ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4130fb98db1SHeiko Stübner RK3288_GMAC_PHY_INTF_SEL_RGMII | 4140fb98db1SHeiko Stübner RK3288_GMAC_RMII_MODE_CLR); 4157ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3, 416eaf70ad1SWadim Egorov DELAY_ENABLE(RK3288, tx_delay, rx_delay) | 4170fb98db1SHeiko Stübner RK3288_GMAC_CLK_RX_DL_CFG(rx_delay) | 4180fb98db1SHeiko Stübner RK3288_GMAC_CLK_TX_DL_CFG(tx_delay)); 4197ad269eaSRoger Chen } 4207ad269eaSRoger Chen 4210fb98db1SHeiko Stübner static void rk3288_set_to_rmii(struct rk_priv_data *bsp_priv) 4227ad269eaSRoger Chen { 4237ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 4247ad269eaSRoger Chen 4257ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 426d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 4277ad269eaSRoger Chen return; 4287ad269eaSRoger Chen } 4297ad269eaSRoger Chen 4307ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4310fb98db1SHeiko Stübner RK3288_GMAC_PHY_INTF_SEL_RMII | RK3288_GMAC_RMII_MODE); 4327ad269eaSRoger Chen } 4337ad269eaSRoger Chen 4340fb98db1SHeiko Stübner static void rk3288_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 4357ad269eaSRoger Chen { 4367ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 4377ad269eaSRoger Chen 4387ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 439d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 4407ad269eaSRoger Chen return; 4417ad269eaSRoger Chen } 4427ad269eaSRoger Chen 4437ad269eaSRoger Chen if (speed == 10) 4440fb98db1SHeiko Stübner regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4450fb98db1SHeiko Stübner RK3288_GMAC_CLK_2_5M); 4467ad269eaSRoger Chen else if (speed == 100) 4470fb98db1SHeiko Stübner regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4480fb98db1SHeiko Stübner RK3288_GMAC_CLK_25M); 4497ad269eaSRoger Chen else if (speed == 1000) 4500fb98db1SHeiko Stübner regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4510fb98db1SHeiko Stübner RK3288_GMAC_CLK_125M); 4527ad269eaSRoger Chen else 4537ad269eaSRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 4547ad269eaSRoger Chen } 4557ad269eaSRoger Chen 4560fb98db1SHeiko Stübner static void rk3288_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 4577ad269eaSRoger Chen { 4587ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 4597ad269eaSRoger Chen 4607ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 461d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 4627ad269eaSRoger Chen return; 4637ad269eaSRoger Chen } 4647ad269eaSRoger Chen 4657ad269eaSRoger Chen if (speed == 10) { 4667ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4670fb98db1SHeiko Stübner RK3288_GMAC_RMII_CLK_2_5M | 4680fb98db1SHeiko Stübner RK3288_GMAC_SPEED_10M); 4697ad269eaSRoger Chen } else if (speed == 100) { 4707ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4710fb98db1SHeiko Stübner RK3288_GMAC_RMII_CLK_25M | 4720fb98db1SHeiko Stübner RK3288_GMAC_SPEED_100M); 4737ad269eaSRoger Chen } else { 4747ad269eaSRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 4757ad269eaSRoger Chen } 4767ad269eaSRoger Chen } 4777ad269eaSRoger Chen 47892c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3288_ops = { 4790fb98db1SHeiko Stübner .set_to_rgmii = rk3288_set_to_rgmii, 4800fb98db1SHeiko Stübner .set_to_rmii = rk3288_set_to_rmii, 4810fb98db1SHeiko Stübner .set_rgmii_speed = rk3288_set_rgmii_speed, 4820fb98db1SHeiko Stübner .set_rmii_speed = rk3288_set_rmii_speed, 4830fb98db1SHeiko Stübner }; 4840fb98db1SHeiko Stübner 485d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON0 0x0900 486d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON1 0x0904 4878bdf63bdSDavid Wu #define RK3328_GRF_MAC_CON2 0x0908 4888bdf63bdSDavid Wu #define RK3328_GRF_MACPHY_CON1 0xb04 489d4ff816eSdavid.wu 490d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON0 */ 491d4ff816eSdavid.wu #define RK3328_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 492d4ff816eSdavid.wu #define RK3328_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 493d4ff816eSdavid.wu 494d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON1 */ 495d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RGMII \ 496d4ff816eSdavid.wu (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6)) 497d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RMII \ 498d4ff816eSdavid.wu (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6)) 499d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL GRF_BIT(3) 500d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 501d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_10M GRF_CLR_BIT(2) 502d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_100M GRF_BIT(2) 503d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_25M GRF_BIT(7) 504d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7) 505d4ff816eSdavid.wu #define RK3328_GMAC_CLK_125M (GRF_CLR_BIT(11) | GRF_CLR_BIT(12)) 506d4ff816eSdavid.wu #define RK3328_GMAC_CLK_25M (GRF_BIT(11) | GRF_BIT(12)) 507d4ff816eSdavid.wu #define RK3328_GMAC_CLK_2_5M (GRF_CLR_BIT(11) | GRF_BIT(12)) 508d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE GRF_BIT(9) 509d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE_CLR GRF_CLR_BIT(9) 510d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0) 511d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0) 512d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1) 513d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(0) 514d4ff816eSdavid.wu 5158bdf63bdSDavid Wu /* RK3328_GRF_MACPHY_CON1 */ 5168bdf63bdSDavid Wu #define RK3328_MACPHY_RMII_MODE GRF_BIT(9) 5178bdf63bdSDavid Wu 518d4ff816eSdavid.wu static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv, 519d4ff816eSdavid.wu int tx_delay, int rx_delay) 520d4ff816eSdavid.wu { 521d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev; 522d4ff816eSdavid.wu 523d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) { 524d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n"); 525d4ff816eSdavid.wu return; 526d4ff816eSdavid.wu } 527d4ff816eSdavid.wu 528d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, 529d4ff816eSdavid.wu RK3328_GMAC_PHY_INTF_SEL_RGMII | 530d4ff816eSdavid.wu RK3328_GMAC_RMII_MODE_CLR | 531d4ff816eSdavid.wu RK3328_GMAC_RXCLK_DLY_ENABLE | 532d4ff816eSdavid.wu RK3328_GMAC_TXCLK_DLY_ENABLE); 533d4ff816eSdavid.wu 534d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON0, 535d4ff816eSdavid.wu RK3328_GMAC_CLK_RX_DL_CFG(rx_delay) | 536d4ff816eSdavid.wu RK3328_GMAC_CLK_TX_DL_CFG(tx_delay)); 537d4ff816eSdavid.wu } 538d4ff816eSdavid.wu 539d4ff816eSdavid.wu static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv) 540d4ff816eSdavid.wu { 541d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev; 5428bdf63bdSDavid Wu unsigned int reg; 543d4ff816eSdavid.wu 544d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) { 545d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n"); 546d4ff816eSdavid.wu return; 547d4ff816eSdavid.wu } 548d4ff816eSdavid.wu 5498bdf63bdSDavid Wu reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 : 5508bdf63bdSDavid Wu RK3328_GRF_MAC_CON1; 5518bdf63bdSDavid Wu 5528bdf63bdSDavid Wu regmap_write(bsp_priv->grf, reg, 553d4ff816eSdavid.wu RK3328_GMAC_PHY_INTF_SEL_RMII | 554d4ff816eSdavid.wu RK3328_GMAC_RMII_MODE); 555d4ff816eSdavid.wu } 556d4ff816eSdavid.wu 557d4ff816eSdavid.wu static void rk3328_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 558d4ff816eSdavid.wu { 559d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev; 560d4ff816eSdavid.wu 561d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) { 562d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n"); 563d4ff816eSdavid.wu return; 564d4ff816eSdavid.wu } 565d4ff816eSdavid.wu 566d4ff816eSdavid.wu if (speed == 10) 567d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, 568d4ff816eSdavid.wu RK3328_GMAC_CLK_2_5M); 569d4ff816eSdavid.wu else if (speed == 100) 570d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, 571d4ff816eSdavid.wu RK3328_GMAC_CLK_25M); 572d4ff816eSdavid.wu else if (speed == 1000) 573d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, 574d4ff816eSdavid.wu RK3328_GMAC_CLK_125M); 575d4ff816eSdavid.wu else 576d4ff816eSdavid.wu dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 577d4ff816eSdavid.wu } 578d4ff816eSdavid.wu 579d4ff816eSdavid.wu static void rk3328_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 580d4ff816eSdavid.wu { 581d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev; 5828bdf63bdSDavid Wu unsigned int reg; 583d4ff816eSdavid.wu 584d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) { 585d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n"); 586d4ff816eSdavid.wu return; 587d4ff816eSdavid.wu } 588d4ff816eSdavid.wu 5898bdf63bdSDavid Wu reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 : 5908bdf63bdSDavid Wu RK3328_GRF_MAC_CON1; 5918bdf63bdSDavid Wu 592d4ff816eSdavid.wu if (speed == 10) 5938bdf63bdSDavid Wu regmap_write(bsp_priv->grf, reg, 594d4ff816eSdavid.wu RK3328_GMAC_RMII_CLK_2_5M | 595d4ff816eSdavid.wu RK3328_GMAC_SPEED_10M); 596d4ff816eSdavid.wu else if (speed == 100) 5978bdf63bdSDavid Wu regmap_write(bsp_priv->grf, reg, 598d4ff816eSdavid.wu RK3328_GMAC_RMII_CLK_25M | 599d4ff816eSdavid.wu RK3328_GMAC_SPEED_100M); 600d4ff816eSdavid.wu else 601d4ff816eSdavid.wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 602d4ff816eSdavid.wu } 603d4ff816eSdavid.wu 6048bdf63bdSDavid Wu static void rk3328_integrated_phy_powerup(struct rk_priv_data *priv) 6058bdf63bdSDavid Wu { 6068bdf63bdSDavid Wu regmap_write(priv->grf, RK3328_GRF_MACPHY_CON1, 6078bdf63bdSDavid Wu RK3328_MACPHY_RMII_MODE); 6088bdf63bdSDavid Wu } 6098bdf63bdSDavid Wu 610d4ff816eSdavid.wu static const struct rk_gmac_ops rk3328_ops = { 611d4ff816eSdavid.wu .set_to_rgmii = rk3328_set_to_rgmii, 612d4ff816eSdavid.wu .set_to_rmii = rk3328_set_to_rmii, 613d4ff816eSdavid.wu .set_rgmii_speed = rk3328_set_rgmii_speed, 614d4ff816eSdavid.wu .set_rmii_speed = rk3328_set_rmii_speed, 6158bdf63bdSDavid Wu .integrated_phy_powerup = rk3328_integrated_phy_powerup, 616d4ff816eSdavid.wu }; 617d4ff816eSdavid.wu 618ba289af8SRoger Chen #define RK3366_GRF_SOC_CON6 0x0418 619ba289af8SRoger Chen #define RK3366_GRF_SOC_CON7 0x041c 620ba289af8SRoger Chen 621ba289af8SRoger Chen /* RK3366_GRF_SOC_CON6 */ 622ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 623ba289af8SRoger Chen GRF_CLR_BIT(11)) 624ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 625ba289af8SRoger Chen GRF_BIT(11)) 626ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL GRF_BIT(8) 627ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 628ba289af8SRoger Chen #define RK3366_GMAC_SPEED_10M GRF_CLR_BIT(7) 629ba289af8SRoger Chen #define RK3366_GMAC_SPEED_100M GRF_BIT(7) 630ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_25M GRF_BIT(3) 631ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 632ba289af8SRoger Chen #define RK3366_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 633ba289af8SRoger Chen #define RK3366_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 634ba289af8SRoger Chen #define RK3366_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 635ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE GRF_BIT(6) 636ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 637ba289af8SRoger Chen 638ba289af8SRoger Chen /* RK3366_GRF_SOC_CON7 */ 639ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 640ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 641ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 642ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 643ba289af8SRoger Chen #define RK3366_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 644ba289af8SRoger Chen #define RK3366_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 645ba289af8SRoger Chen 646ba289af8SRoger Chen static void rk3366_set_to_rgmii(struct rk_priv_data *bsp_priv, 647ba289af8SRoger Chen int tx_delay, int rx_delay) 648ba289af8SRoger Chen { 649ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 650ba289af8SRoger Chen 651ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 652ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 653ba289af8SRoger Chen return; 654ba289af8SRoger Chen } 655ba289af8SRoger Chen 656ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 657ba289af8SRoger Chen RK3366_GMAC_PHY_INTF_SEL_RGMII | 658ba289af8SRoger Chen RK3366_GMAC_RMII_MODE_CLR); 659ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON7, 660eaf70ad1SWadim Egorov DELAY_ENABLE(RK3366, tx_delay, rx_delay) | 661ba289af8SRoger Chen RK3366_GMAC_CLK_RX_DL_CFG(rx_delay) | 662ba289af8SRoger Chen RK3366_GMAC_CLK_TX_DL_CFG(tx_delay)); 663ba289af8SRoger Chen } 664ba289af8SRoger Chen 665ba289af8SRoger Chen static void rk3366_set_to_rmii(struct rk_priv_data *bsp_priv) 666ba289af8SRoger Chen { 667ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 668ba289af8SRoger Chen 669ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 670ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 671ba289af8SRoger Chen return; 672ba289af8SRoger Chen } 673ba289af8SRoger Chen 674ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 675ba289af8SRoger Chen RK3366_GMAC_PHY_INTF_SEL_RMII | RK3366_GMAC_RMII_MODE); 676ba289af8SRoger Chen } 677ba289af8SRoger Chen 678ba289af8SRoger Chen static void rk3366_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 679ba289af8SRoger Chen { 680ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 681ba289af8SRoger Chen 682ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 683ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 684ba289af8SRoger Chen return; 685ba289af8SRoger Chen } 686ba289af8SRoger Chen 687ba289af8SRoger Chen if (speed == 10) 688ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 689ba289af8SRoger Chen RK3366_GMAC_CLK_2_5M); 690ba289af8SRoger Chen else if (speed == 100) 691ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 692ba289af8SRoger Chen RK3366_GMAC_CLK_25M); 693ba289af8SRoger Chen else if (speed == 1000) 694ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 695ba289af8SRoger Chen RK3366_GMAC_CLK_125M); 696ba289af8SRoger Chen else 697ba289af8SRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 698ba289af8SRoger Chen } 699ba289af8SRoger Chen 700ba289af8SRoger Chen static void rk3366_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 701ba289af8SRoger Chen { 702ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 703ba289af8SRoger Chen 704ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 705ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 706ba289af8SRoger Chen return; 707ba289af8SRoger Chen } 708ba289af8SRoger Chen 709ba289af8SRoger Chen if (speed == 10) { 710ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 711ba289af8SRoger Chen RK3366_GMAC_RMII_CLK_2_5M | 712ba289af8SRoger Chen RK3366_GMAC_SPEED_10M); 713ba289af8SRoger Chen } else if (speed == 100) { 714ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 715ba289af8SRoger Chen RK3366_GMAC_RMII_CLK_25M | 716ba289af8SRoger Chen RK3366_GMAC_SPEED_100M); 717ba289af8SRoger Chen } else { 718ba289af8SRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 719ba289af8SRoger Chen } 720ba289af8SRoger Chen } 721ba289af8SRoger Chen 722ba289af8SRoger Chen static const struct rk_gmac_ops rk3366_ops = { 723ba289af8SRoger Chen .set_to_rgmii = rk3366_set_to_rgmii, 724ba289af8SRoger Chen .set_to_rmii = rk3366_set_to_rmii, 725ba289af8SRoger Chen .set_rgmii_speed = rk3366_set_rgmii_speed, 726ba289af8SRoger Chen .set_rmii_speed = rk3366_set_rmii_speed, 727ba289af8SRoger Chen }; 728ba289af8SRoger Chen 729df558854SHeiko Stübner #define RK3368_GRF_SOC_CON15 0x043c 730df558854SHeiko Stübner #define RK3368_GRF_SOC_CON16 0x0440 731df558854SHeiko Stübner 732df558854SHeiko Stübner /* RK3368_GRF_SOC_CON15 */ 733df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 734df558854SHeiko Stübner GRF_CLR_BIT(11)) 735df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 736df558854SHeiko Stübner GRF_BIT(11)) 737df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL GRF_BIT(8) 738df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 739df558854SHeiko Stübner #define RK3368_GMAC_SPEED_10M GRF_CLR_BIT(7) 740df558854SHeiko Stübner #define RK3368_GMAC_SPEED_100M GRF_BIT(7) 741df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_25M GRF_BIT(3) 742df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 743df558854SHeiko Stübner #define RK3368_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 744df558854SHeiko Stübner #define RK3368_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 745df558854SHeiko Stübner #define RK3368_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 746df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE GRF_BIT(6) 747df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 748df558854SHeiko Stübner 749df558854SHeiko Stübner /* RK3368_GRF_SOC_CON16 */ 750df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 751df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 752df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 753df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 754df558854SHeiko Stübner #define RK3368_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 755df558854SHeiko Stübner #define RK3368_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 756df558854SHeiko Stübner 757df558854SHeiko Stübner static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv, 758df558854SHeiko Stübner int tx_delay, int rx_delay) 759df558854SHeiko Stübner { 760df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 761df558854SHeiko Stübner 762df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 763df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 764df558854SHeiko Stübner return; 765df558854SHeiko Stübner } 766df558854SHeiko Stübner 767df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 768df558854SHeiko Stübner RK3368_GMAC_PHY_INTF_SEL_RGMII | 769df558854SHeiko Stübner RK3368_GMAC_RMII_MODE_CLR); 770df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16, 771eaf70ad1SWadim Egorov DELAY_ENABLE(RK3368, tx_delay, rx_delay) | 772df558854SHeiko Stübner RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) | 773df558854SHeiko Stübner RK3368_GMAC_CLK_TX_DL_CFG(tx_delay)); 774df558854SHeiko Stübner } 775df558854SHeiko Stübner 776df558854SHeiko Stübner static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv) 777df558854SHeiko Stübner { 778df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 779df558854SHeiko Stübner 780df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 781df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 782df558854SHeiko Stübner return; 783df558854SHeiko Stübner } 784df558854SHeiko Stübner 785df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 786df558854SHeiko Stübner RK3368_GMAC_PHY_INTF_SEL_RMII | RK3368_GMAC_RMII_MODE); 787df558854SHeiko Stübner } 788df558854SHeiko Stübner 789df558854SHeiko Stübner static void rk3368_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 790df558854SHeiko Stübner { 791df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 792df558854SHeiko Stübner 793df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 794df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 795df558854SHeiko Stübner return; 796df558854SHeiko Stübner } 797df558854SHeiko Stübner 798df558854SHeiko Stübner if (speed == 10) 799df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 800df558854SHeiko Stübner RK3368_GMAC_CLK_2_5M); 801df558854SHeiko Stübner else if (speed == 100) 802df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 803df558854SHeiko Stübner RK3368_GMAC_CLK_25M); 804df558854SHeiko Stübner else if (speed == 1000) 805df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 806df558854SHeiko Stübner RK3368_GMAC_CLK_125M); 807df558854SHeiko Stübner else 808df558854SHeiko Stübner dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 809df558854SHeiko Stübner } 810df558854SHeiko Stübner 811df558854SHeiko Stübner static void rk3368_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 812df558854SHeiko Stübner { 813df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 814df558854SHeiko Stübner 815df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 816df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 817df558854SHeiko Stübner return; 818df558854SHeiko Stübner } 819df558854SHeiko Stübner 820df558854SHeiko Stübner if (speed == 10) { 821df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 822df558854SHeiko Stübner RK3368_GMAC_RMII_CLK_2_5M | 823df558854SHeiko Stübner RK3368_GMAC_SPEED_10M); 824df558854SHeiko Stübner } else if (speed == 100) { 825df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 826df558854SHeiko Stübner RK3368_GMAC_RMII_CLK_25M | 827df558854SHeiko Stübner RK3368_GMAC_SPEED_100M); 828df558854SHeiko Stübner } else { 829df558854SHeiko Stübner dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 830df558854SHeiko Stübner } 831df558854SHeiko Stübner } 832df558854SHeiko Stübner 83392c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3368_ops = { 834df558854SHeiko Stübner .set_to_rgmii = rk3368_set_to_rgmii, 835df558854SHeiko Stübner .set_to_rmii = rk3368_set_to_rmii, 836df558854SHeiko Stübner .set_rgmii_speed = rk3368_set_rgmii_speed, 837df558854SHeiko Stübner .set_rmii_speed = rk3368_set_rmii_speed, 838df558854SHeiko Stübner }; 839df558854SHeiko Stübner 840ba289af8SRoger Chen #define RK3399_GRF_SOC_CON5 0xc214 841ba289af8SRoger Chen #define RK3399_GRF_SOC_CON6 0xc218 842ba289af8SRoger Chen 843ba289af8SRoger Chen /* RK3399_GRF_SOC_CON5 */ 844ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 845ba289af8SRoger Chen GRF_CLR_BIT(11)) 846ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 847ba289af8SRoger Chen GRF_BIT(11)) 848ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL GRF_BIT(8) 849ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 850ba289af8SRoger Chen #define RK3399_GMAC_SPEED_10M GRF_CLR_BIT(7) 851ba289af8SRoger Chen #define RK3399_GMAC_SPEED_100M GRF_BIT(7) 852ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_25M GRF_BIT(3) 853ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 854ba289af8SRoger Chen #define RK3399_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 855ba289af8SRoger Chen #define RK3399_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 856ba289af8SRoger Chen #define RK3399_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 857ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE GRF_BIT(6) 858ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 859ba289af8SRoger Chen 860ba289af8SRoger Chen /* RK3399_GRF_SOC_CON6 */ 861ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 862ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 863ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 864ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 865ba289af8SRoger Chen #define RK3399_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 866ba289af8SRoger Chen #define RK3399_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 867ba289af8SRoger Chen 868ba289af8SRoger Chen static void rk3399_set_to_rgmii(struct rk_priv_data *bsp_priv, 869ba289af8SRoger Chen int tx_delay, int rx_delay) 870ba289af8SRoger Chen { 871ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 872ba289af8SRoger Chen 873ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 874ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 875ba289af8SRoger Chen return; 876ba289af8SRoger Chen } 877ba289af8SRoger Chen 878ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 879ba289af8SRoger Chen RK3399_GMAC_PHY_INTF_SEL_RGMII | 880ba289af8SRoger Chen RK3399_GMAC_RMII_MODE_CLR); 881ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON6, 882eaf70ad1SWadim Egorov DELAY_ENABLE(RK3399, tx_delay, rx_delay) | 883ba289af8SRoger Chen RK3399_GMAC_CLK_RX_DL_CFG(rx_delay) | 884ba289af8SRoger Chen RK3399_GMAC_CLK_TX_DL_CFG(tx_delay)); 885ba289af8SRoger Chen } 886ba289af8SRoger Chen 887ba289af8SRoger Chen static void rk3399_set_to_rmii(struct rk_priv_data *bsp_priv) 888ba289af8SRoger Chen { 889ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 890ba289af8SRoger Chen 891ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 892ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 893ba289af8SRoger Chen return; 894ba289af8SRoger Chen } 895ba289af8SRoger Chen 896ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 897ba289af8SRoger Chen RK3399_GMAC_PHY_INTF_SEL_RMII | RK3399_GMAC_RMII_MODE); 898ba289af8SRoger Chen } 899ba289af8SRoger Chen 900ba289af8SRoger Chen static void rk3399_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 901ba289af8SRoger Chen { 902ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 903ba289af8SRoger Chen 904ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 905ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 906ba289af8SRoger Chen return; 907ba289af8SRoger Chen } 908ba289af8SRoger Chen 909ba289af8SRoger Chen if (speed == 10) 910ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 911ba289af8SRoger Chen RK3399_GMAC_CLK_2_5M); 912ba289af8SRoger Chen else if (speed == 100) 913ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 914ba289af8SRoger Chen RK3399_GMAC_CLK_25M); 915ba289af8SRoger Chen else if (speed == 1000) 916ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 917ba289af8SRoger Chen RK3399_GMAC_CLK_125M); 918ba289af8SRoger Chen else 919ba289af8SRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 920ba289af8SRoger Chen } 921ba289af8SRoger Chen 922ba289af8SRoger Chen static void rk3399_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 923ba289af8SRoger Chen { 924ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 925ba289af8SRoger Chen 926ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 927ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 928ba289af8SRoger Chen return; 929ba289af8SRoger Chen } 930ba289af8SRoger Chen 931ba289af8SRoger Chen if (speed == 10) { 932ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 933ba289af8SRoger Chen RK3399_GMAC_RMII_CLK_2_5M | 934ba289af8SRoger Chen RK3399_GMAC_SPEED_10M); 935ba289af8SRoger Chen } else if (speed == 100) { 936ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 937ba289af8SRoger Chen RK3399_GMAC_RMII_CLK_25M | 938ba289af8SRoger Chen RK3399_GMAC_SPEED_100M); 939ba289af8SRoger Chen } else { 940ba289af8SRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 941ba289af8SRoger Chen } 942ba289af8SRoger Chen } 943ba289af8SRoger Chen 944ba289af8SRoger Chen static const struct rk_gmac_ops rk3399_ops = { 945ba289af8SRoger Chen .set_to_rgmii = rk3399_set_to_rgmii, 946ba289af8SRoger Chen .set_to_rmii = rk3399_set_to_rmii, 947ba289af8SRoger Chen .set_rgmii_speed = rk3399_set_rgmii_speed, 948ba289af8SRoger Chen .set_rmii_speed = rk3399_set_rmii_speed, 949ba289af8SRoger Chen }; 950ba289af8SRoger Chen 95189c9c163SDavid Wu #define RV1108_GRF_GMAC_CON0 0X0900 95289c9c163SDavid Wu 95389c9c163SDavid Wu /* RV1108_GRF_GMAC_CON0 */ 95489c9c163SDavid Wu #define RV1108_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \ 95589c9c163SDavid Wu GRF_BIT(6)) 95689c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL GRF_BIT(3) 95789c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 95889c9c163SDavid Wu #define RV1108_GMAC_SPEED_10M GRF_CLR_BIT(2) 95989c9c163SDavid Wu #define RV1108_GMAC_SPEED_100M GRF_BIT(2) 96089c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_25M GRF_BIT(7) 96189c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7) 96289c9c163SDavid Wu 96389c9c163SDavid Wu static void rv1108_set_to_rmii(struct rk_priv_data *bsp_priv) 96489c9c163SDavid Wu { 96589c9c163SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 96689c9c163SDavid Wu 96789c9c163SDavid Wu if (IS_ERR(bsp_priv->grf)) { 96889c9c163SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 96989c9c163SDavid Wu return; 97089c9c163SDavid Wu } 97189c9c163SDavid Wu 97289c9c163SDavid Wu regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0, 97389c9c163SDavid Wu RV1108_GMAC_PHY_INTF_SEL_RMII); 97489c9c163SDavid Wu } 97589c9c163SDavid Wu 97689c9c163SDavid Wu static void rv1108_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 97789c9c163SDavid Wu { 97889c9c163SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 97989c9c163SDavid Wu 98089c9c163SDavid Wu if (IS_ERR(bsp_priv->grf)) { 98189c9c163SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 98289c9c163SDavid Wu return; 98389c9c163SDavid Wu } 98489c9c163SDavid Wu 98589c9c163SDavid Wu if (speed == 10) { 98689c9c163SDavid Wu regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0, 98789c9c163SDavid Wu RV1108_GMAC_RMII_CLK_2_5M | 98889c9c163SDavid Wu RV1108_GMAC_SPEED_10M); 98989c9c163SDavid Wu } else if (speed == 100) { 99089c9c163SDavid Wu regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0, 99189c9c163SDavid Wu RV1108_GMAC_RMII_CLK_25M | 99289c9c163SDavid Wu RV1108_GMAC_SPEED_100M); 99389c9c163SDavid Wu } else { 99489c9c163SDavid Wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 99589c9c163SDavid Wu } 99689c9c163SDavid Wu } 99789c9c163SDavid Wu 99889c9c163SDavid Wu static const struct rk_gmac_ops rv1108_ops = { 99989c9c163SDavid Wu .set_to_rmii = rv1108_set_to_rmii, 100089c9c163SDavid Wu .set_rmii_speed = rv1108_set_rmii_speed, 100189c9c163SDavid Wu }; 100289c9c163SDavid Wu 1003fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON0 0xb00 1004fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON1 0xb04 1005fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON2 0xb08 1006fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON3 0xb0c 1007fecd4d7eSDavid Wu 1008fecd4d7eSDavid Wu #define RK_MACPHY_ENABLE GRF_BIT(0) 1009fecd4d7eSDavid Wu #define RK_MACPHY_DISABLE GRF_CLR_BIT(0) 1010fecd4d7eSDavid Wu #define RK_MACPHY_CFG_CLK_50M GRF_BIT(14) 1011fecd4d7eSDavid Wu #define RK_GMAC2PHY_RMII_MODE (GRF_BIT(6) | GRF_CLR_BIT(7)) 1012fecd4d7eSDavid Wu #define RK_GRF_CON2_MACPHY_ID HIWORD_UPDATE(0x1234, 0xffff, 0) 1013fecd4d7eSDavid Wu #define RK_GRF_CON3_MACPHY_ID HIWORD_UPDATE(0x35, 0x3f, 0) 1014fecd4d7eSDavid Wu 1015fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerup(struct rk_priv_data *priv) 10167ad269eaSRoger Chen { 1017fecd4d7eSDavid Wu if (priv->ops->integrated_phy_powerup) 1018fecd4d7eSDavid Wu priv->ops->integrated_phy_powerup(priv); 1019fecd4d7eSDavid Wu 1020fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M); 1021fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE); 1022fecd4d7eSDavid Wu 1023fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID); 1024fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID); 1025fecd4d7eSDavid Wu 1026fecd4d7eSDavid Wu if (priv->phy_reset) { 1027fecd4d7eSDavid Wu /* PHY needs to be disabled before trying to reset it */ 1028fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE); 1029fecd4d7eSDavid Wu if (priv->phy_reset) 1030fecd4d7eSDavid Wu reset_control_assert(priv->phy_reset); 1031fecd4d7eSDavid Wu usleep_range(10, 20); 1032fecd4d7eSDavid Wu if (priv->phy_reset) 1033fecd4d7eSDavid Wu reset_control_deassert(priv->phy_reset); 1034fecd4d7eSDavid Wu usleep_range(10, 20); 1035fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE); 1036fecd4d7eSDavid Wu msleep(30); 1037fecd4d7eSDavid Wu } 1038fecd4d7eSDavid Wu } 1039fecd4d7eSDavid Wu 1040fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerdown(struct rk_priv_data *priv) 1041fecd4d7eSDavid Wu { 1042fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE); 1043fecd4d7eSDavid Wu if (priv->phy_reset) 1044fecd4d7eSDavid Wu reset_control_assert(priv->phy_reset); 1045fecd4d7eSDavid Wu } 1046fecd4d7eSDavid Wu 1047fecd4d7eSDavid Wu static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat) 1048fecd4d7eSDavid Wu { 1049fecd4d7eSDavid Wu struct rk_priv_data *bsp_priv = plat->bsp_priv; 10507ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 1051fecd4d7eSDavid Wu int ret; 10527ad269eaSRoger Chen 10537ad269eaSRoger Chen bsp_priv->clk_enabled = false; 10547ad269eaSRoger Chen 10557ad269eaSRoger Chen bsp_priv->mac_clk_rx = devm_clk_get(dev, "mac_clk_rx"); 10567ad269eaSRoger Chen if (IS_ERR(bsp_priv->mac_clk_rx)) 1057d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1058d42202dcSRomain Perier "mac_clk_rx"); 10597ad269eaSRoger Chen 10607ad269eaSRoger Chen bsp_priv->mac_clk_tx = devm_clk_get(dev, "mac_clk_tx"); 10617ad269eaSRoger Chen if (IS_ERR(bsp_priv->mac_clk_tx)) 1062d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1063d42202dcSRomain Perier "mac_clk_tx"); 10647ad269eaSRoger Chen 10657ad269eaSRoger Chen bsp_priv->aclk_mac = devm_clk_get(dev, "aclk_mac"); 10667ad269eaSRoger Chen if (IS_ERR(bsp_priv->aclk_mac)) 1067d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1068d42202dcSRomain Perier "aclk_mac"); 10697ad269eaSRoger Chen 10707ad269eaSRoger Chen bsp_priv->pclk_mac = devm_clk_get(dev, "pclk_mac"); 10717ad269eaSRoger Chen if (IS_ERR(bsp_priv->pclk_mac)) 1072d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1073d42202dcSRomain Perier "pclk_mac"); 10747ad269eaSRoger Chen 10757ad269eaSRoger Chen bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth"); 10767ad269eaSRoger Chen if (IS_ERR(bsp_priv->clk_mac)) 1077d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1078d42202dcSRomain Perier "stmmaceth"); 10797ad269eaSRoger Chen 10807ad269eaSRoger Chen if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) { 10817ad269eaSRoger Chen bsp_priv->clk_mac_ref = devm_clk_get(dev, "clk_mac_ref"); 10827ad269eaSRoger Chen if (IS_ERR(bsp_priv->clk_mac_ref)) 1083d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1084d42202dcSRomain Perier "clk_mac_ref"); 10857ad269eaSRoger Chen 10867ad269eaSRoger Chen if (!bsp_priv->clock_input) { 10877ad269eaSRoger Chen bsp_priv->clk_mac_refout = 10887ad269eaSRoger Chen devm_clk_get(dev, "clk_mac_refout"); 10897ad269eaSRoger Chen if (IS_ERR(bsp_priv->clk_mac_refout)) 1090d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1091d42202dcSRomain Perier "clk_mac_refout"); 10927ad269eaSRoger Chen } 10937ad269eaSRoger Chen } 10947ad269eaSRoger Chen 109523c94d63SDavid Wu bsp_priv->clk_mac_speed = devm_clk_get(dev, "clk_mac_speed"); 109623c94d63SDavid Wu if (IS_ERR(bsp_priv->clk_mac_speed)) 109723c94d63SDavid Wu dev_err(dev, "cannot get clock %s\n", "clk_mac_speed"); 109823c94d63SDavid Wu 10997ad269eaSRoger Chen if (bsp_priv->clock_input) { 1100d42202dcSRomain Perier dev_info(dev, "clock input from PHY\n"); 11017ad269eaSRoger Chen } else { 11027ad269eaSRoger Chen if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) 1103c48fa33cSHeiko Stübner clk_set_rate(bsp_priv->clk_mac, 50000000); 11047ad269eaSRoger Chen } 11057ad269eaSRoger Chen 1106fecd4d7eSDavid Wu if (plat->phy_node && bsp_priv->integrated_phy) { 1107fecd4d7eSDavid Wu bsp_priv->clk_phy = of_clk_get(plat->phy_node, 0); 1108fecd4d7eSDavid Wu if (IS_ERR(bsp_priv->clk_phy)) { 1109fecd4d7eSDavid Wu ret = PTR_ERR(bsp_priv->clk_phy); 1110fecd4d7eSDavid Wu dev_err(dev, "Cannot get PHY clock: %d\n", ret); 1111fecd4d7eSDavid Wu return -EINVAL; 1112fecd4d7eSDavid Wu } 1113fecd4d7eSDavid Wu clk_set_rate(bsp_priv->clk_phy, 50000000); 1114fecd4d7eSDavid Wu } 1115fecd4d7eSDavid Wu 11167ad269eaSRoger Chen return 0; 11177ad269eaSRoger Chen } 11187ad269eaSRoger Chen 11197ad269eaSRoger Chen static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable) 11207ad269eaSRoger Chen { 1121428ad1bcSLABBE Corentin int phy_iface = bsp_priv->phy_iface; 11227ad269eaSRoger Chen 11237ad269eaSRoger Chen if (enable) { 11247ad269eaSRoger Chen if (!bsp_priv->clk_enabled) { 11257ad269eaSRoger Chen if (phy_iface == PHY_INTERFACE_MODE_RMII) { 11267ad269eaSRoger Chen if (!IS_ERR(bsp_priv->mac_clk_rx)) 11277ad269eaSRoger Chen clk_prepare_enable( 11287ad269eaSRoger Chen bsp_priv->mac_clk_rx); 11297ad269eaSRoger Chen 11307ad269eaSRoger Chen if (!IS_ERR(bsp_priv->clk_mac_ref)) 11317ad269eaSRoger Chen clk_prepare_enable( 11327ad269eaSRoger Chen bsp_priv->clk_mac_ref); 11337ad269eaSRoger Chen 11347ad269eaSRoger Chen if (!IS_ERR(bsp_priv->clk_mac_refout)) 11357ad269eaSRoger Chen clk_prepare_enable( 11367ad269eaSRoger Chen bsp_priv->clk_mac_refout); 11377ad269eaSRoger Chen } 11387ad269eaSRoger Chen 1139fecd4d7eSDavid Wu if (!IS_ERR(bsp_priv->clk_phy)) 1140fecd4d7eSDavid Wu clk_prepare_enable(bsp_priv->clk_phy); 1141fecd4d7eSDavid Wu 11427ad269eaSRoger Chen if (!IS_ERR(bsp_priv->aclk_mac)) 11437ad269eaSRoger Chen clk_prepare_enable(bsp_priv->aclk_mac); 11447ad269eaSRoger Chen 11457ad269eaSRoger Chen if (!IS_ERR(bsp_priv->pclk_mac)) 11467ad269eaSRoger Chen clk_prepare_enable(bsp_priv->pclk_mac); 11477ad269eaSRoger Chen 11487ad269eaSRoger Chen if (!IS_ERR(bsp_priv->mac_clk_tx)) 11497ad269eaSRoger Chen clk_prepare_enable(bsp_priv->mac_clk_tx); 11507ad269eaSRoger Chen 115123c94d63SDavid Wu if (!IS_ERR(bsp_priv->clk_mac_speed)) 115223c94d63SDavid Wu clk_prepare_enable(bsp_priv->clk_mac_speed); 115323c94d63SDavid Wu 11547ad269eaSRoger Chen /** 11557ad269eaSRoger Chen * if (!IS_ERR(bsp_priv->clk_mac)) 11567ad269eaSRoger Chen * clk_prepare_enable(bsp_priv->clk_mac); 11577ad269eaSRoger Chen */ 11587ad269eaSRoger Chen mdelay(5); 11597ad269eaSRoger Chen bsp_priv->clk_enabled = true; 11607ad269eaSRoger Chen } 11617ad269eaSRoger Chen } else { 11627ad269eaSRoger Chen if (bsp_priv->clk_enabled) { 11637ad269eaSRoger Chen if (phy_iface == PHY_INTERFACE_MODE_RMII) { 116493120ebaSYueHaibing clk_disable_unprepare(bsp_priv->mac_clk_rx); 11657ad269eaSRoger Chen 116693120ebaSYueHaibing clk_disable_unprepare(bsp_priv->clk_mac_ref); 11677ad269eaSRoger Chen 116893120ebaSYueHaibing clk_disable_unprepare(bsp_priv->clk_mac_refout); 11697ad269eaSRoger Chen } 11707ad269eaSRoger Chen 1171fecd4d7eSDavid Wu clk_disable_unprepare(bsp_priv->clk_phy); 1172fecd4d7eSDavid Wu 11737ad269eaSRoger Chen clk_disable_unprepare(bsp_priv->aclk_mac); 11747ad269eaSRoger Chen 11757ad269eaSRoger Chen clk_disable_unprepare(bsp_priv->pclk_mac); 11767ad269eaSRoger Chen 11777ad269eaSRoger Chen clk_disable_unprepare(bsp_priv->mac_clk_tx); 117823c94d63SDavid Wu 117923c94d63SDavid Wu clk_disable_unprepare(bsp_priv->clk_mac_speed); 11807ad269eaSRoger Chen /** 11817ad269eaSRoger Chen * if (!IS_ERR(bsp_priv->clk_mac)) 11827ad269eaSRoger Chen * clk_disable_unprepare(bsp_priv->clk_mac); 11837ad269eaSRoger Chen */ 11847ad269eaSRoger Chen bsp_priv->clk_enabled = false; 11857ad269eaSRoger Chen } 11867ad269eaSRoger Chen } 11877ad269eaSRoger Chen 11887ad269eaSRoger Chen return 0; 11897ad269eaSRoger Chen } 11907ad269eaSRoger Chen 11917ad269eaSRoger Chen static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable) 11927ad269eaSRoger Chen { 11932e12f536SRomain Perier struct regulator *ldo = bsp_priv->regulator; 11947ad269eaSRoger Chen int ret; 11957ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 11967ad269eaSRoger Chen 11973b25528eSChen-Yu Tsai if (!ldo) 11983b25528eSChen-Yu Tsai return 0; 11997ad269eaSRoger Chen 12007ad269eaSRoger Chen if (enable) { 12017ad269eaSRoger Chen ret = regulator_enable(ldo); 12022e12f536SRomain Perier if (ret) 1203d42202dcSRomain Perier dev_err(dev, "fail to enable phy-supply\n"); 12047ad269eaSRoger Chen } else { 12057ad269eaSRoger Chen ret = regulator_disable(ldo); 12062e12f536SRomain Perier if (ret) 1207d42202dcSRomain Perier dev_err(dev, "fail to disable phy-supply\n"); 12087ad269eaSRoger Chen } 12097ad269eaSRoger Chen 12107ad269eaSRoger Chen return 0; 12117ad269eaSRoger Chen } 12127ad269eaSRoger Chen 12130fb98db1SHeiko Stübner static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev, 1214fecd4d7eSDavid Wu struct plat_stmmacenet_data *plat, 121592c2588fSJoachim Eastwood const struct rk_gmac_ops *ops) 12167ad269eaSRoger Chen { 12177ad269eaSRoger Chen struct rk_priv_data *bsp_priv; 12187ad269eaSRoger Chen struct device *dev = &pdev->dev; 12197ad269eaSRoger Chen int ret; 12207ad269eaSRoger Chen const char *strings = NULL; 12217ad269eaSRoger Chen int value; 12227ad269eaSRoger Chen 12237ad269eaSRoger Chen bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL); 12247ad269eaSRoger Chen if (!bsp_priv) 12257ad269eaSRoger Chen return ERR_PTR(-ENOMEM); 12267ad269eaSRoger Chen 12270c65b2b9SAndrew Lunn of_get_phy_mode(dev->of_node, &bsp_priv->phy_iface); 12280fb98db1SHeiko Stübner bsp_priv->ops = ops; 12297ad269eaSRoger Chen 12302e12f536SRomain Perier bsp_priv->regulator = devm_regulator_get_optional(dev, "phy"); 12312e12f536SRomain Perier if (IS_ERR(bsp_priv->regulator)) { 12322e12f536SRomain Perier if (PTR_ERR(bsp_priv->regulator) == -EPROBE_DEFER) { 12332e12f536SRomain Perier dev_err(dev, "phy regulator is not available yet, deferred probing\n"); 12342e12f536SRomain Perier return ERR_PTR(-EPROBE_DEFER); 12352e12f536SRomain Perier } 12362e12f536SRomain Perier dev_err(dev, "no regulator found\n"); 12372e12f536SRomain Perier bsp_priv->regulator = NULL; 12387ad269eaSRoger Chen } 12397ad269eaSRoger Chen 12407ad269eaSRoger Chen ret = of_property_read_string(dev->of_node, "clock_in_out", &strings); 12417ad269eaSRoger Chen if (ret) { 1242d42202dcSRomain Perier dev_err(dev, "Can not read property: clock_in_out.\n"); 12437ad269eaSRoger Chen bsp_priv->clock_input = true; 12447ad269eaSRoger Chen } else { 1245d42202dcSRomain Perier dev_info(dev, "clock input or output? (%s).\n", 1246d42202dcSRomain Perier strings); 12477ad269eaSRoger Chen if (!strcmp(strings, "input")) 12487ad269eaSRoger Chen bsp_priv->clock_input = true; 12497ad269eaSRoger Chen else 12507ad269eaSRoger Chen bsp_priv->clock_input = false; 12517ad269eaSRoger Chen } 12527ad269eaSRoger Chen 12537ad269eaSRoger Chen ret = of_property_read_u32(dev->of_node, "tx_delay", &value); 12547ad269eaSRoger Chen if (ret) { 12557ad269eaSRoger Chen bsp_priv->tx_delay = 0x30; 1256d42202dcSRomain Perier dev_err(dev, "Can not read property: tx_delay."); 1257d42202dcSRomain Perier dev_err(dev, "set tx_delay to 0x%x\n", 1258d42202dcSRomain Perier bsp_priv->tx_delay); 12597ad269eaSRoger Chen } else { 1260d42202dcSRomain Perier dev_info(dev, "TX delay(0x%x).\n", value); 12617ad269eaSRoger Chen bsp_priv->tx_delay = value; 12627ad269eaSRoger Chen } 12637ad269eaSRoger Chen 12647ad269eaSRoger Chen ret = of_property_read_u32(dev->of_node, "rx_delay", &value); 12657ad269eaSRoger Chen if (ret) { 12667ad269eaSRoger Chen bsp_priv->rx_delay = 0x10; 1267d42202dcSRomain Perier dev_err(dev, "Can not read property: rx_delay."); 1268d42202dcSRomain Perier dev_err(dev, "set rx_delay to 0x%x\n", 1269d42202dcSRomain Perier bsp_priv->rx_delay); 12707ad269eaSRoger Chen } else { 1271d42202dcSRomain Perier dev_info(dev, "RX delay(0x%x).\n", value); 12727ad269eaSRoger Chen bsp_priv->rx_delay = value; 12737ad269eaSRoger Chen } 12747ad269eaSRoger Chen 12757ad269eaSRoger Chen bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node, 12767ad269eaSRoger Chen "rockchip,grf"); 12777ad269eaSRoger Chen 1278fecd4d7eSDavid Wu if (plat->phy_node) { 1279fecd4d7eSDavid Wu bsp_priv->integrated_phy = of_property_read_bool(plat->phy_node, 1280fecd4d7eSDavid Wu "phy-is-integrated"); 1281fecd4d7eSDavid Wu if (bsp_priv->integrated_phy) { 1282fecd4d7eSDavid Wu bsp_priv->phy_reset = of_reset_control_get(plat->phy_node, NULL); 1283fecd4d7eSDavid Wu if (IS_ERR(bsp_priv->phy_reset)) { 1284fecd4d7eSDavid Wu dev_err(&pdev->dev, "No PHY reset control found.\n"); 1285fecd4d7eSDavid Wu bsp_priv->phy_reset = NULL; 1286fecd4d7eSDavid Wu } 1287fecd4d7eSDavid Wu } 1288fecd4d7eSDavid Wu } 1289fecd4d7eSDavid Wu dev_info(dev, "integrated PHY? (%s).\n", 1290fecd4d7eSDavid Wu bsp_priv->integrated_phy ? "yes" : "no"); 1291fecd4d7eSDavid Wu 1292fecd4d7eSDavid Wu bsp_priv->pdev = pdev; 129345383f52SRoger Chen 129445383f52SRoger Chen return bsp_priv; 129545383f52SRoger Chen } 129645383f52SRoger Chen 129745383f52SRoger Chen static int rk_gmac_powerup(struct rk_priv_data *bsp_priv) 129845383f52SRoger Chen { 129945383f52SRoger Chen int ret; 130045383f52SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 130145383f52SRoger Chen 1302f217bfdeSHeiko Stübner ret = gmac_clk_enable(bsp_priv, true); 1303f217bfdeSHeiko Stübner if (ret) 1304f217bfdeSHeiko Stübner return ret; 1305f217bfdeSHeiko Stübner 13067ad269eaSRoger Chen /*rmii or rgmii*/ 1307eaf70ad1SWadim Egorov switch (bsp_priv->phy_iface) { 1308eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII: 1309d42202dcSRomain Perier dev_info(dev, "init for RGMII\n"); 13100fb98db1SHeiko Stübner bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 13110fb98db1SHeiko Stübner bsp_priv->rx_delay); 1312eaf70ad1SWadim Egorov break; 1313eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_ID: 1314eaf70ad1SWadim Egorov dev_info(dev, "init for RGMII_ID\n"); 1315eaf70ad1SWadim Egorov bsp_priv->ops->set_to_rgmii(bsp_priv, 0, 0); 1316eaf70ad1SWadim Egorov break; 1317eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_RXID: 1318eaf70ad1SWadim Egorov dev_info(dev, "init for RGMII_RXID\n"); 1319eaf70ad1SWadim Egorov bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 0); 1320eaf70ad1SWadim Egorov break; 1321eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_TXID: 1322eaf70ad1SWadim Egorov dev_info(dev, "init for RGMII_TXID\n"); 1323eaf70ad1SWadim Egorov bsp_priv->ops->set_to_rgmii(bsp_priv, 0, bsp_priv->rx_delay); 1324eaf70ad1SWadim Egorov break; 1325eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RMII: 1326d42202dcSRomain Perier dev_info(dev, "init for RMII\n"); 13270fb98db1SHeiko Stübner bsp_priv->ops->set_to_rmii(bsp_priv); 1328eaf70ad1SWadim Egorov break; 1329eaf70ad1SWadim Egorov default: 1330d42202dcSRomain Perier dev_err(dev, "NO interface defined!\n"); 13317ad269eaSRoger Chen } 13327ad269eaSRoger Chen 13337ad269eaSRoger Chen ret = phy_power_on(bsp_priv, true); 1334c69c29a1SAlexey Khoroshilov if (ret) { 1335c69c29a1SAlexey Khoroshilov gmac_clk_enable(bsp_priv, false); 13367ad269eaSRoger Chen return ret; 1337c69c29a1SAlexey Khoroshilov } 13387ad269eaSRoger Chen 13392c896fb0SDavid Wu pm_runtime_enable(dev); 13402c896fb0SDavid Wu pm_runtime_get_sync(dev); 13412c896fb0SDavid Wu 1342fecd4d7eSDavid Wu if (bsp_priv->integrated_phy) 1343fecd4d7eSDavid Wu rk_gmac_integrated_phy_powerup(bsp_priv); 1344fecd4d7eSDavid Wu 13457ad269eaSRoger Chen return 0; 13467ad269eaSRoger Chen } 13477ad269eaSRoger Chen 1348229666c1SVincent Palatin static void rk_gmac_powerdown(struct rk_priv_data *gmac) 13497ad269eaSRoger Chen { 13502c896fb0SDavid Wu struct device *dev = &gmac->pdev->dev; 13512c896fb0SDavid Wu 1352fecd4d7eSDavid Wu if (gmac->integrated_phy) 1353fecd4d7eSDavid Wu rk_gmac_integrated_phy_powerdown(gmac); 1354fecd4d7eSDavid Wu 13552c896fb0SDavid Wu pm_runtime_put_sync(dev); 13562c896fb0SDavid Wu pm_runtime_disable(dev); 13572c896fb0SDavid Wu 13587ad269eaSRoger Chen phy_power_on(gmac, false); 13597ad269eaSRoger Chen gmac_clk_enable(gmac, false); 13607ad269eaSRoger Chen } 13617ad269eaSRoger Chen 13627ad269eaSRoger Chen static void rk_fix_speed(void *priv, unsigned int speed) 13637ad269eaSRoger Chen { 13647ad269eaSRoger Chen struct rk_priv_data *bsp_priv = priv; 13657ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 13667ad269eaSRoger Chen 1367eaf70ad1SWadim Egorov switch (bsp_priv->phy_iface) { 1368eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII: 1369eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_ID: 1370eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_RXID: 1371eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_TXID: 13720fb98db1SHeiko Stübner bsp_priv->ops->set_rgmii_speed(bsp_priv, speed); 1373eaf70ad1SWadim Egorov break; 1374eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RMII: 13750fb98db1SHeiko Stübner bsp_priv->ops->set_rmii_speed(bsp_priv, speed); 1376eaf70ad1SWadim Egorov break; 1377eaf70ad1SWadim Egorov default: 13787ad269eaSRoger Chen dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface); 13797ad269eaSRoger Chen } 1380eaf70ad1SWadim Egorov } 13817ad269eaSRoger Chen 138227ffefd2SJoachim Eastwood static int rk_gmac_probe(struct platform_device *pdev) 138327ffefd2SJoachim Eastwood { 138427ffefd2SJoachim Eastwood struct plat_stmmacenet_data *plat_dat; 138527ffefd2SJoachim Eastwood struct stmmac_resources stmmac_res; 1386f529f182SJoachim Eastwood const struct rk_gmac_ops *data; 138727ffefd2SJoachim Eastwood int ret; 138827ffefd2SJoachim Eastwood 1389149adeddSJoachim Eastwood data = of_device_get_match_data(&pdev->dev); 1390149adeddSJoachim Eastwood if (!data) { 1391149adeddSJoachim Eastwood dev_err(&pdev->dev, "no of match data provided\n"); 1392149adeddSJoachim Eastwood return -EINVAL; 1393149adeddSJoachim Eastwood } 1394149adeddSJoachim Eastwood 139527ffefd2SJoachim Eastwood ret = stmmac_get_platform_resources(pdev, &stmmac_res); 139627ffefd2SJoachim Eastwood if (ret) 139727ffefd2SJoachim Eastwood return ret; 139827ffefd2SJoachim Eastwood 139927ffefd2SJoachim Eastwood plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac); 140027ffefd2SJoachim Eastwood if (IS_ERR(plat_dat)) 140127ffefd2SJoachim Eastwood return PTR_ERR(plat_dat); 140227ffefd2SJoachim Eastwood 140327ffefd2SJoachim Eastwood plat_dat->has_gmac = true; 140427ffefd2SJoachim Eastwood plat_dat->fix_mac_speed = rk_fix_speed; 140527ffefd2SJoachim Eastwood 1406fecd4d7eSDavid Wu plat_dat->bsp_priv = rk_gmac_setup(pdev, plat_dat, data); 1407d2ed0a77SJohan Hovold if (IS_ERR(plat_dat->bsp_priv)) { 1408d2ed0a77SJohan Hovold ret = PTR_ERR(plat_dat->bsp_priv); 1409d2ed0a77SJohan Hovold goto err_remove_config_dt; 1410d2ed0a77SJohan Hovold } 141127ffefd2SJoachim Eastwood 1412fecd4d7eSDavid Wu ret = rk_gmac_clk_init(plat_dat); 1413fecd4d7eSDavid Wu if (ret) 1414*9de9aa48SEmil Renner Berthing goto err_remove_config_dt; 1415fecd4d7eSDavid Wu 141607a5e769SJoachim Eastwood ret = rk_gmac_powerup(plat_dat->bsp_priv); 141727ffefd2SJoachim Eastwood if (ret) 1418d2ed0a77SJohan Hovold goto err_remove_config_dt; 141927ffefd2SJoachim Eastwood 14202d222656SJohan Hovold ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); 14212d222656SJohan Hovold if (ret) 14222745529aSDavid S. Miller goto err_gmac_powerdown; 14232d222656SJohan Hovold 14242d222656SJohan Hovold return 0; 14252d222656SJohan Hovold 14262745529aSDavid S. Miller err_gmac_powerdown: 14272745529aSDavid S. Miller rk_gmac_powerdown(plat_dat->bsp_priv); 1428d2ed0a77SJohan Hovold err_remove_config_dt: 1429d2ed0a77SJohan Hovold stmmac_remove_config_dt(pdev, plat_dat); 14302d222656SJohan Hovold 14312d222656SJohan Hovold return ret; 143227ffefd2SJoachim Eastwood } 143327ffefd2SJoachim Eastwood 14340de8c4c9SJoachim Eastwood static int rk_gmac_remove(struct platform_device *pdev) 14350de8c4c9SJoachim Eastwood { 14360de8c4c9SJoachim Eastwood struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(&pdev->dev); 14370de8c4c9SJoachim Eastwood int ret = stmmac_dvr_remove(&pdev->dev); 14380de8c4c9SJoachim Eastwood 14390de8c4c9SJoachim Eastwood rk_gmac_powerdown(bsp_priv); 14400de8c4c9SJoachim Eastwood 14410de8c4c9SJoachim Eastwood return ret; 14420de8c4c9SJoachim Eastwood } 14430de8c4c9SJoachim Eastwood 14445619468aSJoachim Eastwood #ifdef CONFIG_PM_SLEEP 14455619468aSJoachim Eastwood static int rk_gmac_suspend(struct device *dev) 14465619468aSJoachim Eastwood { 14475619468aSJoachim Eastwood struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev); 14485619468aSJoachim Eastwood int ret = stmmac_suspend(dev); 14495619468aSJoachim Eastwood 14505619468aSJoachim Eastwood /* Keep the PHY up if we use Wake-on-Lan. */ 14515619468aSJoachim Eastwood if (!device_may_wakeup(dev)) { 14525619468aSJoachim Eastwood rk_gmac_powerdown(bsp_priv); 14535619468aSJoachim Eastwood bsp_priv->suspended = true; 14545619468aSJoachim Eastwood } 14555619468aSJoachim Eastwood 14565619468aSJoachim Eastwood return ret; 14575619468aSJoachim Eastwood } 14585619468aSJoachim Eastwood 14595619468aSJoachim Eastwood static int rk_gmac_resume(struct device *dev) 14605619468aSJoachim Eastwood { 14615619468aSJoachim Eastwood struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev); 14625619468aSJoachim Eastwood 14635619468aSJoachim Eastwood /* The PHY was up for Wake-on-Lan. */ 14645619468aSJoachim Eastwood if (bsp_priv->suspended) { 14655619468aSJoachim Eastwood rk_gmac_powerup(bsp_priv); 14665619468aSJoachim Eastwood bsp_priv->suspended = false; 14675619468aSJoachim Eastwood } 14685619468aSJoachim Eastwood 14695619468aSJoachim Eastwood return stmmac_resume(dev); 14705619468aSJoachim Eastwood } 14715619468aSJoachim Eastwood #endif /* CONFIG_PM_SLEEP */ 14725619468aSJoachim Eastwood 14735619468aSJoachim Eastwood static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume); 14745619468aSJoachim Eastwood 1475e0fb4013SJoachim Eastwood static const struct of_device_id rk_gmac_dwmac_match[] = { 147623c94d63SDavid Wu { .compatible = "rockchip,px30-gmac", .data = &px30_ops }, 147705946876SDavid Wu { .compatible = "rockchip,rk3128-gmac", .data = &rk3128_ops }, 1478e7ffd812SXing Zheng { .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops }, 1479f529f182SJoachim Eastwood { .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops }, 1480d4ff816eSdavid.wu { .compatible = "rockchip,rk3328-gmac", .data = &rk3328_ops }, 1481ba289af8SRoger Chen { .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops }, 1482f529f182SJoachim Eastwood { .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops }, 1483ba289af8SRoger Chen { .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops }, 148489c9c163SDavid Wu { .compatible = "rockchip,rv1108-gmac", .data = &rv1108_ops }, 1485e0fb4013SJoachim Eastwood { } 1486e0fb4013SJoachim Eastwood }; 1487e0fb4013SJoachim Eastwood MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match); 1488e0fb4013SJoachim Eastwood 1489e0fb4013SJoachim Eastwood static struct platform_driver rk_gmac_dwmac_driver = { 149027ffefd2SJoachim Eastwood .probe = rk_gmac_probe, 14910de8c4c9SJoachim Eastwood .remove = rk_gmac_remove, 1492e0fb4013SJoachim Eastwood .driver = { 1493e0fb4013SJoachim Eastwood .name = "rk_gmac-dwmac", 14945619468aSJoachim Eastwood .pm = &rk_gmac_pm_ops, 1495e0fb4013SJoachim Eastwood .of_match_table = rk_gmac_dwmac_match, 1496e0fb4013SJoachim Eastwood }, 1497e0fb4013SJoachim Eastwood }; 1498e0fb4013SJoachim Eastwood module_platform_driver(rk_gmac_dwmac_driver); 1499e0fb4013SJoachim Eastwood 1500e0fb4013SJoachim Eastwood MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>"); 1501e0fb4013SJoachim Eastwood MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer"); 1502e0fb4013SJoachim Eastwood MODULE_LICENSE("GPL"); 1503