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> 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 485b4ac9456STobias Schramm #define RK3308_GRF_MAC_CON0 0x04a0 486b4ac9456STobias Schramm 487b4ac9456STobias Schramm /* RK3308_GRF_MAC_CON0 */ 488b4ac9456STobias Schramm #define RK3308_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(2) | GRF_CLR_BIT(3) | \ 489b4ac9456STobias Schramm GRF_BIT(4)) 490b4ac9456STobias Schramm #define RK3308_GMAC_FLOW_CTRL GRF_BIT(3) 491b4ac9456STobias Schramm #define RK3308_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 492b4ac9456STobias Schramm #define RK3308_GMAC_SPEED_10M GRF_CLR_BIT(0) 493b4ac9456STobias Schramm #define RK3308_GMAC_SPEED_100M GRF_BIT(0) 494b4ac9456STobias Schramm 495b4ac9456STobias Schramm static void rk3308_set_to_rmii(struct rk_priv_data *bsp_priv) 496b4ac9456STobias Schramm { 497b4ac9456STobias Schramm struct device *dev = &bsp_priv->pdev->dev; 498b4ac9456STobias Schramm 499b4ac9456STobias Schramm if (IS_ERR(bsp_priv->grf)) { 500b4ac9456STobias Schramm dev_err(dev, "Missing rockchip,grf property\n"); 501b4ac9456STobias Schramm return; 502b4ac9456STobias Schramm } 503b4ac9456STobias Schramm 504b4ac9456STobias Schramm regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0, 505b4ac9456STobias Schramm RK3308_GMAC_PHY_INTF_SEL_RMII); 506b4ac9456STobias Schramm } 507b4ac9456STobias Schramm 508b4ac9456STobias Schramm static void rk3308_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 509b4ac9456STobias Schramm { 510b4ac9456STobias Schramm struct device *dev = &bsp_priv->pdev->dev; 511b4ac9456STobias Schramm 512b4ac9456STobias Schramm if (IS_ERR(bsp_priv->grf)) { 513b4ac9456STobias Schramm dev_err(dev, "Missing rockchip,grf property\n"); 514b4ac9456STobias Schramm return; 515b4ac9456STobias Schramm } 516b4ac9456STobias Schramm 517b4ac9456STobias Schramm if (speed == 10) { 518b4ac9456STobias Schramm regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0, 519b4ac9456STobias Schramm RK3308_GMAC_SPEED_10M); 520b4ac9456STobias Schramm } else if (speed == 100) { 521b4ac9456STobias Schramm regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0, 522b4ac9456STobias Schramm RK3308_GMAC_SPEED_100M); 523b4ac9456STobias Schramm } else { 524b4ac9456STobias Schramm dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 525b4ac9456STobias Schramm } 526b4ac9456STobias Schramm } 527b4ac9456STobias Schramm 528b4ac9456STobias Schramm static const struct rk_gmac_ops rk3308_ops = { 529b4ac9456STobias Schramm .set_to_rmii = rk3308_set_to_rmii, 530b4ac9456STobias Schramm .set_rmii_speed = rk3308_set_rmii_speed, 531b4ac9456STobias Schramm }; 532b4ac9456STobias Schramm 533d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON0 0x0900 534d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON1 0x0904 5358bdf63bdSDavid Wu #define RK3328_GRF_MAC_CON2 0x0908 5368bdf63bdSDavid Wu #define RK3328_GRF_MACPHY_CON1 0xb04 537d4ff816eSdavid.wu 538d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON0 */ 539d4ff816eSdavid.wu #define RK3328_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 540d4ff816eSdavid.wu #define RK3328_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 541d4ff816eSdavid.wu 542d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON1 */ 543d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RGMII \ 544d4ff816eSdavid.wu (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6)) 545d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RMII \ 546d4ff816eSdavid.wu (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6)) 547d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL GRF_BIT(3) 548d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 549d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_10M GRF_CLR_BIT(2) 550d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_100M GRF_BIT(2) 551d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_25M GRF_BIT(7) 552d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7) 553d4ff816eSdavid.wu #define RK3328_GMAC_CLK_125M (GRF_CLR_BIT(11) | GRF_CLR_BIT(12)) 554d4ff816eSdavid.wu #define RK3328_GMAC_CLK_25M (GRF_BIT(11) | GRF_BIT(12)) 555d4ff816eSdavid.wu #define RK3328_GMAC_CLK_2_5M (GRF_CLR_BIT(11) | GRF_BIT(12)) 556d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE GRF_BIT(9) 557d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE_CLR GRF_CLR_BIT(9) 558d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0) 559d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0) 560d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1) 561d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(0) 562d4ff816eSdavid.wu 5638bdf63bdSDavid Wu /* RK3328_GRF_MACPHY_CON1 */ 5648bdf63bdSDavid Wu #define RK3328_MACPHY_RMII_MODE GRF_BIT(9) 5658bdf63bdSDavid Wu 566d4ff816eSdavid.wu static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv, 567d4ff816eSdavid.wu int tx_delay, int rx_delay) 568d4ff816eSdavid.wu { 569d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev; 570d4ff816eSdavid.wu 571d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) { 572d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n"); 573d4ff816eSdavid.wu return; 574d4ff816eSdavid.wu } 575d4ff816eSdavid.wu 576d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, 577d4ff816eSdavid.wu RK3328_GMAC_PHY_INTF_SEL_RGMII | 578d4ff816eSdavid.wu RK3328_GMAC_RMII_MODE_CLR | 579d4ff816eSdavid.wu RK3328_GMAC_RXCLK_DLY_ENABLE | 580d4ff816eSdavid.wu RK3328_GMAC_TXCLK_DLY_ENABLE); 581d4ff816eSdavid.wu 582d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON0, 583d4ff816eSdavid.wu RK3328_GMAC_CLK_RX_DL_CFG(rx_delay) | 584d4ff816eSdavid.wu RK3328_GMAC_CLK_TX_DL_CFG(tx_delay)); 585d4ff816eSdavid.wu } 586d4ff816eSdavid.wu 587d4ff816eSdavid.wu static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv) 588d4ff816eSdavid.wu { 589d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev; 5908bdf63bdSDavid Wu unsigned int reg; 591d4ff816eSdavid.wu 592d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) { 593d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n"); 594d4ff816eSdavid.wu return; 595d4ff816eSdavid.wu } 596d4ff816eSdavid.wu 5978bdf63bdSDavid Wu reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 : 5988bdf63bdSDavid Wu RK3328_GRF_MAC_CON1; 5998bdf63bdSDavid Wu 6008bdf63bdSDavid Wu regmap_write(bsp_priv->grf, reg, 601d4ff816eSdavid.wu RK3328_GMAC_PHY_INTF_SEL_RMII | 602d4ff816eSdavid.wu RK3328_GMAC_RMII_MODE); 603d4ff816eSdavid.wu } 604d4ff816eSdavid.wu 605d4ff816eSdavid.wu static void rk3328_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 606d4ff816eSdavid.wu { 607d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev; 608d4ff816eSdavid.wu 609d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) { 610d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n"); 611d4ff816eSdavid.wu return; 612d4ff816eSdavid.wu } 613d4ff816eSdavid.wu 614d4ff816eSdavid.wu if (speed == 10) 615d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, 616d4ff816eSdavid.wu RK3328_GMAC_CLK_2_5M); 617d4ff816eSdavid.wu else if (speed == 100) 618d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, 619d4ff816eSdavid.wu RK3328_GMAC_CLK_25M); 620d4ff816eSdavid.wu else if (speed == 1000) 621d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, 622d4ff816eSdavid.wu RK3328_GMAC_CLK_125M); 623d4ff816eSdavid.wu else 624d4ff816eSdavid.wu dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 625d4ff816eSdavid.wu } 626d4ff816eSdavid.wu 627d4ff816eSdavid.wu static void rk3328_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 628d4ff816eSdavid.wu { 629d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev; 6308bdf63bdSDavid Wu unsigned int reg; 631d4ff816eSdavid.wu 632d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) { 633d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n"); 634d4ff816eSdavid.wu return; 635d4ff816eSdavid.wu } 636d4ff816eSdavid.wu 6378bdf63bdSDavid Wu reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 : 6388bdf63bdSDavid Wu RK3328_GRF_MAC_CON1; 6398bdf63bdSDavid Wu 640d4ff816eSdavid.wu if (speed == 10) 6418bdf63bdSDavid Wu regmap_write(bsp_priv->grf, reg, 642d4ff816eSdavid.wu RK3328_GMAC_RMII_CLK_2_5M | 643d4ff816eSdavid.wu RK3328_GMAC_SPEED_10M); 644d4ff816eSdavid.wu else if (speed == 100) 6458bdf63bdSDavid Wu regmap_write(bsp_priv->grf, reg, 646d4ff816eSdavid.wu RK3328_GMAC_RMII_CLK_25M | 647d4ff816eSdavid.wu RK3328_GMAC_SPEED_100M); 648d4ff816eSdavid.wu else 649d4ff816eSdavid.wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 650d4ff816eSdavid.wu } 651d4ff816eSdavid.wu 6528bdf63bdSDavid Wu static void rk3328_integrated_phy_powerup(struct rk_priv_data *priv) 6538bdf63bdSDavid Wu { 6548bdf63bdSDavid Wu regmap_write(priv->grf, RK3328_GRF_MACPHY_CON1, 6558bdf63bdSDavid Wu RK3328_MACPHY_RMII_MODE); 6568bdf63bdSDavid Wu } 6578bdf63bdSDavid Wu 658d4ff816eSdavid.wu static const struct rk_gmac_ops rk3328_ops = { 659d4ff816eSdavid.wu .set_to_rgmii = rk3328_set_to_rgmii, 660d4ff816eSdavid.wu .set_to_rmii = rk3328_set_to_rmii, 661d4ff816eSdavid.wu .set_rgmii_speed = rk3328_set_rgmii_speed, 662d4ff816eSdavid.wu .set_rmii_speed = rk3328_set_rmii_speed, 6638bdf63bdSDavid Wu .integrated_phy_powerup = rk3328_integrated_phy_powerup, 664d4ff816eSdavid.wu }; 665d4ff816eSdavid.wu 666ba289af8SRoger Chen #define RK3366_GRF_SOC_CON6 0x0418 667ba289af8SRoger Chen #define RK3366_GRF_SOC_CON7 0x041c 668ba289af8SRoger Chen 669ba289af8SRoger Chen /* RK3366_GRF_SOC_CON6 */ 670ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 671ba289af8SRoger Chen GRF_CLR_BIT(11)) 672ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 673ba289af8SRoger Chen GRF_BIT(11)) 674ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL GRF_BIT(8) 675ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 676ba289af8SRoger Chen #define RK3366_GMAC_SPEED_10M GRF_CLR_BIT(7) 677ba289af8SRoger Chen #define RK3366_GMAC_SPEED_100M GRF_BIT(7) 678ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_25M GRF_BIT(3) 679ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 680ba289af8SRoger Chen #define RK3366_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 681ba289af8SRoger Chen #define RK3366_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 682ba289af8SRoger Chen #define RK3366_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 683ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE GRF_BIT(6) 684ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 685ba289af8SRoger Chen 686ba289af8SRoger Chen /* RK3366_GRF_SOC_CON7 */ 687ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 688ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 689ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 690ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 691ba289af8SRoger Chen #define RK3366_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 692ba289af8SRoger Chen #define RK3366_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 693ba289af8SRoger Chen 694ba289af8SRoger Chen static void rk3366_set_to_rgmii(struct rk_priv_data *bsp_priv, 695ba289af8SRoger Chen int tx_delay, int rx_delay) 696ba289af8SRoger Chen { 697ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 698ba289af8SRoger Chen 699ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 700ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 701ba289af8SRoger Chen return; 702ba289af8SRoger Chen } 703ba289af8SRoger Chen 704ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 705ba289af8SRoger Chen RK3366_GMAC_PHY_INTF_SEL_RGMII | 706ba289af8SRoger Chen RK3366_GMAC_RMII_MODE_CLR); 707ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON7, 708eaf70ad1SWadim Egorov DELAY_ENABLE(RK3366, tx_delay, rx_delay) | 709ba289af8SRoger Chen RK3366_GMAC_CLK_RX_DL_CFG(rx_delay) | 710ba289af8SRoger Chen RK3366_GMAC_CLK_TX_DL_CFG(tx_delay)); 711ba289af8SRoger Chen } 712ba289af8SRoger Chen 713ba289af8SRoger Chen static void rk3366_set_to_rmii(struct rk_priv_data *bsp_priv) 714ba289af8SRoger Chen { 715ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 716ba289af8SRoger Chen 717ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 718ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 719ba289af8SRoger Chen return; 720ba289af8SRoger Chen } 721ba289af8SRoger Chen 722ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 723ba289af8SRoger Chen RK3366_GMAC_PHY_INTF_SEL_RMII | RK3366_GMAC_RMII_MODE); 724ba289af8SRoger Chen } 725ba289af8SRoger Chen 726ba289af8SRoger Chen static void rk3366_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 727ba289af8SRoger Chen { 728ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 729ba289af8SRoger Chen 730ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 731ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 732ba289af8SRoger Chen return; 733ba289af8SRoger Chen } 734ba289af8SRoger Chen 735ba289af8SRoger Chen if (speed == 10) 736ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 737ba289af8SRoger Chen RK3366_GMAC_CLK_2_5M); 738ba289af8SRoger Chen else if (speed == 100) 739ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 740ba289af8SRoger Chen RK3366_GMAC_CLK_25M); 741ba289af8SRoger Chen else if (speed == 1000) 742ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 743ba289af8SRoger Chen RK3366_GMAC_CLK_125M); 744ba289af8SRoger Chen else 745ba289af8SRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 746ba289af8SRoger Chen } 747ba289af8SRoger Chen 748ba289af8SRoger Chen static void rk3366_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 749ba289af8SRoger Chen { 750ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 751ba289af8SRoger Chen 752ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 753ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 754ba289af8SRoger Chen return; 755ba289af8SRoger Chen } 756ba289af8SRoger Chen 757ba289af8SRoger Chen if (speed == 10) { 758ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 759ba289af8SRoger Chen RK3366_GMAC_RMII_CLK_2_5M | 760ba289af8SRoger Chen RK3366_GMAC_SPEED_10M); 761ba289af8SRoger Chen } else if (speed == 100) { 762ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 763ba289af8SRoger Chen RK3366_GMAC_RMII_CLK_25M | 764ba289af8SRoger Chen RK3366_GMAC_SPEED_100M); 765ba289af8SRoger Chen } else { 766ba289af8SRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 767ba289af8SRoger Chen } 768ba289af8SRoger Chen } 769ba289af8SRoger Chen 770ba289af8SRoger Chen static const struct rk_gmac_ops rk3366_ops = { 771ba289af8SRoger Chen .set_to_rgmii = rk3366_set_to_rgmii, 772ba289af8SRoger Chen .set_to_rmii = rk3366_set_to_rmii, 773ba289af8SRoger Chen .set_rgmii_speed = rk3366_set_rgmii_speed, 774ba289af8SRoger Chen .set_rmii_speed = rk3366_set_rmii_speed, 775ba289af8SRoger Chen }; 776ba289af8SRoger Chen 777df558854SHeiko Stübner #define RK3368_GRF_SOC_CON15 0x043c 778df558854SHeiko Stübner #define RK3368_GRF_SOC_CON16 0x0440 779df558854SHeiko Stübner 780df558854SHeiko Stübner /* RK3368_GRF_SOC_CON15 */ 781df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 782df558854SHeiko Stübner GRF_CLR_BIT(11)) 783df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 784df558854SHeiko Stübner GRF_BIT(11)) 785df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL GRF_BIT(8) 786df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 787df558854SHeiko Stübner #define RK3368_GMAC_SPEED_10M GRF_CLR_BIT(7) 788df558854SHeiko Stübner #define RK3368_GMAC_SPEED_100M GRF_BIT(7) 789df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_25M GRF_BIT(3) 790df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 791df558854SHeiko Stübner #define RK3368_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 792df558854SHeiko Stübner #define RK3368_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 793df558854SHeiko Stübner #define RK3368_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 794df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE GRF_BIT(6) 795df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 796df558854SHeiko Stübner 797df558854SHeiko Stübner /* RK3368_GRF_SOC_CON16 */ 798df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 799df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 800df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 801df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 802df558854SHeiko Stübner #define RK3368_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 803df558854SHeiko Stübner #define RK3368_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 804df558854SHeiko Stübner 805df558854SHeiko Stübner static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv, 806df558854SHeiko Stübner int tx_delay, int rx_delay) 807df558854SHeiko Stübner { 808df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 809df558854SHeiko Stübner 810df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 811df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 812df558854SHeiko Stübner return; 813df558854SHeiko Stübner } 814df558854SHeiko Stübner 815df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 816df558854SHeiko Stübner RK3368_GMAC_PHY_INTF_SEL_RGMII | 817df558854SHeiko Stübner RK3368_GMAC_RMII_MODE_CLR); 818df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16, 819eaf70ad1SWadim Egorov DELAY_ENABLE(RK3368, tx_delay, rx_delay) | 820df558854SHeiko Stübner RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) | 821df558854SHeiko Stübner RK3368_GMAC_CLK_TX_DL_CFG(tx_delay)); 822df558854SHeiko Stübner } 823df558854SHeiko Stübner 824df558854SHeiko Stübner static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv) 825df558854SHeiko Stübner { 826df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 827df558854SHeiko Stübner 828df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 829df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 830df558854SHeiko Stübner return; 831df558854SHeiko Stübner } 832df558854SHeiko Stübner 833df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 834df558854SHeiko Stübner RK3368_GMAC_PHY_INTF_SEL_RMII | RK3368_GMAC_RMII_MODE); 835df558854SHeiko Stübner } 836df558854SHeiko Stübner 837df558854SHeiko Stübner static void rk3368_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 838df558854SHeiko Stübner { 839df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 840df558854SHeiko Stübner 841df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 842df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 843df558854SHeiko Stübner return; 844df558854SHeiko Stübner } 845df558854SHeiko Stübner 846df558854SHeiko Stübner if (speed == 10) 847df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 848df558854SHeiko Stübner RK3368_GMAC_CLK_2_5M); 849df558854SHeiko Stübner else if (speed == 100) 850df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 851df558854SHeiko Stübner RK3368_GMAC_CLK_25M); 852df558854SHeiko Stübner else if (speed == 1000) 853df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 854df558854SHeiko Stübner RK3368_GMAC_CLK_125M); 855df558854SHeiko Stübner else 856df558854SHeiko Stübner dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 857df558854SHeiko Stübner } 858df558854SHeiko Stübner 859df558854SHeiko Stübner static void rk3368_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 860df558854SHeiko Stübner { 861df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 862df558854SHeiko Stübner 863df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 864df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 865df558854SHeiko Stübner return; 866df558854SHeiko Stübner } 867df558854SHeiko Stübner 868df558854SHeiko Stübner if (speed == 10) { 869df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 870df558854SHeiko Stübner RK3368_GMAC_RMII_CLK_2_5M | 871df558854SHeiko Stübner RK3368_GMAC_SPEED_10M); 872df558854SHeiko Stübner } else if (speed == 100) { 873df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 874df558854SHeiko Stübner RK3368_GMAC_RMII_CLK_25M | 875df558854SHeiko Stübner RK3368_GMAC_SPEED_100M); 876df558854SHeiko Stübner } else { 877df558854SHeiko Stübner dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 878df558854SHeiko Stübner } 879df558854SHeiko Stübner } 880df558854SHeiko Stübner 88192c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3368_ops = { 882df558854SHeiko Stübner .set_to_rgmii = rk3368_set_to_rgmii, 883df558854SHeiko Stübner .set_to_rmii = rk3368_set_to_rmii, 884df558854SHeiko Stübner .set_rgmii_speed = rk3368_set_rgmii_speed, 885df558854SHeiko Stübner .set_rmii_speed = rk3368_set_rmii_speed, 886df558854SHeiko Stübner }; 887df558854SHeiko Stübner 888ba289af8SRoger Chen #define RK3399_GRF_SOC_CON5 0xc214 889ba289af8SRoger Chen #define RK3399_GRF_SOC_CON6 0xc218 890ba289af8SRoger Chen 891ba289af8SRoger Chen /* RK3399_GRF_SOC_CON5 */ 892ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 893ba289af8SRoger Chen GRF_CLR_BIT(11)) 894ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 895ba289af8SRoger Chen GRF_BIT(11)) 896ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL GRF_BIT(8) 897ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 898ba289af8SRoger Chen #define RK3399_GMAC_SPEED_10M GRF_CLR_BIT(7) 899ba289af8SRoger Chen #define RK3399_GMAC_SPEED_100M GRF_BIT(7) 900ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_25M GRF_BIT(3) 901ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 902ba289af8SRoger Chen #define RK3399_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 903ba289af8SRoger Chen #define RK3399_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 904ba289af8SRoger Chen #define RK3399_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 905ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE GRF_BIT(6) 906ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 907ba289af8SRoger Chen 908ba289af8SRoger Chen /* RK3399_GRF_SOC_CON6 */ 909ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 910ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 911ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 912ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 913ba289af8SRoger Chen #define RK3399_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 914ba289af8SRoger Chen #define RK3399_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 915ba289af8SRoger Chen 916ba289af8SRoger Chen static void rk3399_set_to_rgmii(struct rk_priv_data *bsp_priv, 917ba289af8SRoger Chen int tx_delay, int rx_delay) 918ba289af8SRoger Chen { 919ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 920ba289af8SRoger Chen 921ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 922ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 923ba289af8SRoger Chen return; 924ba289af8SRoger Chen } 925ba289af8SRoger Chen 926ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 927ba289af8SRoger Chen RK3399_GMAC_PHY_INTF_SEL_RGMII | 928ba289af8SRoger Chen RK3399_GMAC_RMII_MODE_CLR); 929ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON6, 930eaf70ad1SWadim Egorov DELAY_ENABLE(RK3399, tx_delay, rx_delay) | 931ba289af8SRoger Chen RK3399_GMAC_CLK_RX_DL_CFG(rx_delay) | 932ba289af8SRoger Chen RK3399_GMAC_CLK_TX_DL_CFG(tx_delay)); 933ba289af8SRoger Chen } 934ba289af8SRoger Chen 935ba289af8SRoger Chen static void rk3399_set_to_rmii(struct rk_priv_data *bsp_priv) 936ba289af8SRoger Chen { 937ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 938ba289af8SRoger Chen 939ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 940ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 941ba289af8SRoger Chen return; 942ba289af8SRoger Chen } 943ba289af8SRoger Chen 944ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 945ba289af8SRoger Chen RK3399_GMAC_PHY_INTF_SEL_RMII | RK3399_GMAC_RMII_MODE); 946ba289af8SRoger Chen } 947ba289af8SRoger Chen 948ba289af8SRoger Chen static void rk3399_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 949ba289af8SRoger Chen { 950ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 951ba289af8SRoger Chen 952ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 953ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 954ba289af8SRoger Chen return; 955ba289af8SRoger Chen } 956ba289af8SRoger Chen 957ba289af8SRoger Chen if (speed == 10) 958ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 959ba289af8SRoger Chen RK3399_GMAC_CLK_2_5M); 960ba289af8SRoger Chen else if (speed == 100) 961ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 962ba289af8SRoger Chen RK3399_GMAC_CLK_25M); 963ba289af8SRoger Chen else if (speed == 1000) 964ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 965ba289af8SRoger Chen RK3399_GMAC_CLK_125M); 966ba289af8SRoger Chen else 967ba289af8SRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 968ba289af8SRoger Chen } 969ba289af8SRoger Chen 970ba289af8SRoger Chen static void rk3399_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 971ba289af8SRoger Chen { 972ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 973ba289af8SRoger Chen 974ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 975ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 976ba289af8SRoger Chen return; 977ba289af8SRoger Chen } 978ba289af8SRoger Chen 979ba289af8SRoger Chen if (speed == 10) { 980ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 981ba289af8SRoger Chen RK3399_GMAC_RMII_CLK_2_5M | 982ba289af8SRoger Chen RK3399_GMAC_SPEED_10M); 983ba289af8SRoger Chen } else if (speed == 100) { 984ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 985ba289af8SRoger Chen RK3399_GMAC_RMII_CLK_25M | 986ba289af8SRoger Chen RK3399_GMAC_SPEED_100M); 987ba289af8SRoger Chen } else { 988ba289af8SRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 989ba289af8SRoger Chen } 990ba289af8SRoger Chen } 991ba289af8SRoger Chen 992ba289af8SRoger Chen static const struct rk_gmac_ops rk3399_ops = { 993ba289af8SRoger Chen .set_to_rgmii = rk3399_set_to_rgmii, 994ba289af8SRoger Chen .set_to_rmii = rk3399_set_to_rmii, 995ba289af8SRoger Chen .set_rgmii_speed = rk3399_set_rgmii_speed, 996ba289af8SRoger Chen .set_rmii_speed = rk3399_set_rmii_speed, 997ba289af8SRoger Chen }; 998ba289af8SRoger Chen 99989c9c163SDavid Wu #define RV1108_GRF_GMAC_CON0 0X0900 100089c9c163SDavid Wu 100189c9c163SDavid Wu /* RV1108_GRF_GMAC_CON0 */ 100289c9c163SDavid Wu #define RV1108_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \ 100389c9c163SDavid Wu GRF_BIT(6)) 100489c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL GRF_BIT(3) 100589c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 100689c9c163SDavid Wu #define RV1108_GMAC_SPEED_10M GRF_CLR_BIT(2) 100789c9c163SDavid Wu #define RV1108_GMAC_SPEED_100M GRF_BIT(2) 100889c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_25M GRF_BIT(7) 100989c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7) 101089c9c163SDavid Wu 101189c9c163SDavid Wu static void rv1108_set_to_rmii(struct rk_priv_data *bsp_priv) 101289c9c163SDavid Wu { 101389c9c163SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 101489c9c163SDavid Wu 101589c9c163SDavid Wu if (IS_ERR(bsp_priv->grf)) { 101689c9c163SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 101789c9c163SDavid Wu return; 101889c9c163SDavid Wu } 101989c9c163SDavid Wu 102089c9c163SDavid Wu regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0, 102189c9c163SDavid Wu RV1108_GMAC_PHY_INTF_SEL_RMII); 102289c9c163SDavid Wu } 102389c9c163SDavid Wu 102489c9c163SDavid Wu static void rv1108_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 102589c9c163SDavid Wu { 102689c9c163SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 102789c9c163SDavid Wu 102889c9c163SDavid Wu if (IS_ERR(bsp_priv->grf)) { 102989c9c163SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 103089c9c163SDavid Wu return; 103189c9c163SDavid Wu } 103289c9c163SDavid Wu 103389c9c163SDavid Wu if (speed == 10) { 103489c9c163SDavid Wu regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0, 103589c9c163SDavid Wu RV1108_GMAC_RMII_CLK_2_5M | 103689c9c163SDavid Wu RV1108_GMAC_SPEED_10M); 103789c9c163SDavid Wu } else if (speed == 100) { 103889c9c163SDavid Wu regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0, 103989c9c163SDavid Wu RV1108_GMAC_RMII_CLK_25M | 104089c9c163SDavid Wu RV1108_GMAC_SPEED_100M); 104189c9c163SDavid Wu } else { 104289c9c163SDavid Wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 104389c9c163SDavid Wu } 104489c9c163SDavid Wu } 104589c9c163SDavid Wu 104689c9c163SDavid Wu static const struct rk_gmac_ops rv1108_ops = { 104789c9c163SDavid Wu .set_to_rmii = rv1108_set_to_rmii, 104889c9c163SDavid Wu .set_rmii_speed = rv1108_set_rmii_speed, 104989c9c163SDavid Wu }; 105089c9c163SDavid Wu 1051fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON0 0xb00 1052fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON1 0xb04 1053fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON2 0xb08 1054fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON3 0xb0c 1055fecd4d7eSDavid Wu 1056fecd4d7eSDavid Wu #define RK_MACPHY_ENABLE GRF_BIT(0) 1057fecd4d7eSDavid Wu #define RK_MACPHY_DISABLE GRF_CLR_BIT(0) 1058fecd4d7eSDavid Wu #define RK_MACPHY_CFG_CLK_50M GRF_BIT(14) 1059fecd4d7eSDavid Wu #define RK_GMAC2PHY_RMII_MODE (GRF_BIT(6) | GRF_CLR_BIT(7)) 1060fecd4d7eSDavid Wu #define RK_GRF_CON2_MACPHY_ID HIWORD_UPDATE(0x1234, 0xffff, 0) 1061fecd4d7eSDavid Wu #define RK_GRF_CON3_MACPHY_ID HIWORD_UPDATE(0x35, 0x3f, 0) 1062fecd4d7eSDavid Wu 1063fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerup(struct rk_priv_data *priv) 10647ad269eaSRoger Chen { 1065fecd4d7eSDavid Wu if (priv->ops->integrated_phy_powerup) 1066fecd4d7eSDavid Wu priv->ops->integrated_phy_powerup(priv); 1067fecd4d7eSDavid Wu 1068fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M); 1069fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE); 1070fecd4d7eSDavid Wu 1071fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID); 1072fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID); 1073fecd4d7eSDavid Wu 1074fecd4d7eSDavid Wu if (priv->phy_reset) { 1075fecd4d7eSDavid Wu /* PHY needs to be disabled before trying to reset it */ 1076fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE); 1077fecd4d7eSDavid Wu if (priv->phy_reset) 1078fecd4d7eSDavid Wu reset_control_assert(priv->phy_reset); 1079fecd4d7eSDavid Wu usleep_range(10, 20); 1080fecd4d7eSDavid Wu if (priv->phy_reset) 1081fecd4d7eSDavid Wu reset_control_deassert(priv->phy_reset); 1082fecd4d7eSDavid Wu usleep_range(10, 20); 1083fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE); 1084fecd4d7eSDavid Wu msleep(30); 1085fecd4d7eSDavid Wu } 1086fecd4d7eSDavid Wu } 1087fecd4d7eSDavid Wu 1088fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerdown(struct rk_priv_data *priv) 1089fecd4d7eSDavid Wu { 1090fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE); 1091fecd4d7eSDavid Wu if (priv->phy_reset) 1092fecd4d7eSDavid Wu reset_control_assert(priv->phy_reset); 1093fecd4d7eSDavid Wu } 1094fecd4d7eSDavid Wu 1095fecd4d7eSDavid Wu static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat) 1096fecd4d7eSDavid Wu { 1097fecd4d7eSDavid Wu struct rk_priv_data *bsp_priv = plat->bsp_priv; 10987ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 1099fecd4d7eSDavid Wu int ret; 11007ad269eaSRoger Chen 11017ad269eaSRoger Chen bsp_priv->clk_enabled = false; 11027ad269eaSRoger Chen 11037ad269eaSRoger Chen bsp_priv->mac_clk_rx = devm_clk_get(dev, "mac_clk_rx"); 11047ad269eaSRoger Chen if (IS_ERR(bsp_priv->mac_clk_rx)) 1105d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1106d42202dcSRomain Perier "mac_clk_rx"); 11077ad269eaSRoger Chen 11087ad269eaSRoger Chen bsp_priv->mac_clk_tx = devm_clk_get(dev, "mac_clk_tx"); 11097ad269eaSRoger Chen if (IS_ERR(bsp_priv->mac_clk_tx)) 1110d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1111d42202dcSRomain Perier "mac_clk_tx"); 11127ad269eaSRoger Chen 11137ad269eaSRoger Chen bsp_priv->aclk_mac = devm_clk_get(dev, "aclk_mac"); 11147ad269eaSRoger Chen if (IS_ERR(bsp_priv->aclk_mac)) 1115d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1116d42202dcSRomain Perier "aclk_mac"); 11177ad269eaSRoger Chen 11187ad269eaSRoger Chen bsp_priv->pclk_mac = devm_clk_get(dev, "pclk_mac"); 11197ad269eaSRoger Chen if (IS_ERR(bsp_priv->pclk_mac)) 1120d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1121d42202dcSRomain Perier "pclk_mac"); 11227ad269eaSRoger Chen 11237ad269eaSRoger Chen bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth"); 11247ad269eaSRoger Chen if (IS_ERR(bsp_priv->clk_mac)) 1125d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1126d42202dcSRomain Perier "stmmaceth"); 11277ad269eaSRoger Chen 11287ad269eaSRoger Chen if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) { 11297ad269eaSRoger Chen bsp_priv->clk_mac_ref = devm_clk_get(dev, "clk_mac_ref"); 11307ad269eaSRoger Chen if (IS_ERR(bsp_priv->clk_mac_ref)) 1131d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1132d42202dcSRomain Perier "clk_mac_ref"); 11337ad269eaSRoger Chen 11347ad269eaSRoger Chen if (!bsp_priv->clock_input) { 11357ad269eaSRoger Chen bsp_priv->clk_mac_refout = 11367ad269eaSRoger Chen devm_clk_get(dev, "clk_mac_refout"); 11377ad269eaSRoger Chen if (IS_ERR(bsp_priv->clk_mac_refout)) 1138d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1139d42202dcSRomain Perier "clk_mac_refout"); 11407ad269eaSRoger Chen } 11417ad269eaSRoger Chen } 11427ad269eaSRoger Chen 114323c94d63SDavid Wu bsp_priv->clk_mac_speed = devm_clk_get(dev, "clk_mac_speed"); 114423c94d63SDavid Wu if (IS_ERR(bsp_priv->clk_mac_speed)) 114523c94d63SDavid Wu dev_err(dev, "cannot get clock %s\n", "clk_mac_speed"); 114623c94d63SDavid Wu 11477ad269eaSRoger Chen if (bsp_priv->clock_input) { 1148d42202dcSRomain Perier dev_info(dev, "clock input from PHY\n"); 11497ad269eaSRoger Chen } else { 11507ad269eaSRoger Chen if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) 1151c48fa33cSHeiko Stübner clk_set_rate(bsp_priv->clk_mac, 50000000); 11527ad269eaSRoger Chen } 11537ad269eaSRoger Chen 1154fecd4d7eSDavid Wu if (plat->phy_node && bsp_priv->integrated_phy) { 1155fecd4d7eSDavid Wu bsp_priv->clk_phy = of_clk_get(plat->phy_node, 0); 1156fecd4d7eSDavid Wu if (IS_ERR(bsp_priv->clk_phy)) { 1157fecd4d7eSDavid Wu ret = PTR_ERR(bsp_priv->clk_phy); 1158fecd4d7eSDavid Wu dev_err(dev, "Cannot get PHY clock: %d\n", ret); 1159fecd4d7eSDavid Wu return -EINVAL; 1160fecd4d7eSDavid Wu } 1161fecd4d7eSDavid Wu clk_set_rate(bsp_priv->clk_phy, 50000000); 1162fecd4d7eSDavid Wu } 1163fecd4d7eSDavid Wu 11647ad269eaSRoger Chen return 0; 11657ad269eaSRoger Chen } 11667ad269eaSRoger Chen 11677ad269eaSRoger Chen static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable) 11687ad269eaSRoger Chen { 1169428ad1bcSLABBE Corentin int phy_iface = bsp_priv->phy_iface; 11707ad269eaSRoger Chen 11717ad269eaSRoger Chen if (enable) { 11727ad269eaSRoger Chen if (!bsp_priv->clk_enabled) { 11737ad269eaSRoger Chen if (phy_iface == PHY_INTERFACE_MODE_RMII) { 11747ad269eaSRoger Chen if (!IS_ERR(bsp_priv->mac_clk_rx)) 11757ad269eaSRoger Chen clk_prepare_enable( 11767ad269eaSRoger Chen bsp_priv->mac_clk_rx); 11777ad269eaSRoger Chen 11787ad269eaSRoger Chen if (!IS_ERR(bsp_priv->clk_mac_ref)) 11797ad269eaSRoger Chen clk_prepare_enable( 11807ad269eaSRoger Chen bsp_priv->clk_mac_ref); 11817ad269eaSRoger Chen 11827ad269eaSRoger Chen if (!IS_ERR(bsp_priv->clk_mac_refout)) 11837ad269eaSRoger Chen clk_prepare_enable( 11847ad269eaSRoger Chen bsp_priv->clk_mac_refout); 11857ad269eaSRoger Chen } 11867ad269eaSRoger Chen 1187fecd4d7eSDavid Wu if (!IS_ERR(bsp_priv->clk_phy)) 1188fecd4d7eSDavid Wu clk_prepare_enable(bsp_priv->clk_phy); 1189fecd4d7eSDavid Wu 11907ad269eaSRoger Chen if (!IS_ERR(bsp_priv->aclk_mac)) 11917ad269eaSRoger Chen clk_prepare_enable(bsp_priv->aclk_mac); 11927ad269eaSRoger Chen 11937ad269eaSRoger Chen if (!IS_ERR(bsp_priv->pclk_mac)) 11947ad269eaSRoger Chen clk_prepare_enable(bsp_priv->pclk_mac); 11957ad269eaSRoger Chen 11967ad269eaSRoger Chen if (!IS_ERR(bsp_priv->mac_clk_tx)) 11977ad269eaSRoger Chen clk_prepare_enable(bsp_priv->mac_clk_tx); 11987ad269eaSRoger Chen 119923c94d63SDavid Wu if (!IS_ERR(bsp_priv->clk_mac_speed)) 120023c94d63SDavid Wu clk_prepare_enable(bsp_priv->clk_mac_speed); 120123c94d63SDavid Wu 12027ad269eaSRoger Chen /** 12037ad269eaSRoger Chen * if (!IS_ERR(bsp_priv->clk_mac)) 12047ad269eaSRoger Chen * clk_prepare_enable(bsp_priv->clk_mac); 12057ad269eaSRoger Chen */ 12067ad269eaSRoger Chen mdelay(5); 12077ad269eaSRoger Chen bsp_priv->clk_enabled = true; 12087ad269eaSRoger Chen } 12097ad269eaSRoger Chen } else { 12107ad269eaSRoger Chen if (bsp_priv->clk_enabled) { 12117ad269eaSRoger Chen if (phy_iface == PHY_INTERFACE_MODE_RMII) { 121293120ebaSYueHaibing clk_disable_unprepare(bsp_priv->mac_clk_rx); 12137ad269eaSRoger Chen 121493120ebaSYueHaibing clk_disable_unprepare(bsp_priv->clk_mac_ref); 12157ad269eaSRoger Chen 121693120ebaSYueHaibing clk_disable_unprepare(bsp_priv->clk_mac_refout); 12177ad269eaSRoger Chen } 12187ad269eaSRoger Chen 1219fecd4d7eSDavid Wu clk_disable_unprepare(bsp_priv->clk_phy); 1220fecd4d7eSDavid Wu 12217ad269eaSRoger Chen clk_disable_unprepare(bsp_priv->aclk_mac); 12227ad269eaSRoger Chen 12237ad269eaSRoger Chen clk_disable_unprepare(bsp_priv->pclk_mac); 12247ad269eaSRoger Chen 12257ad269eaSRoger Chen clk_disable_unprepare(bsp_priv->mac_clk_tx); 122623c94d63SDavid Wu 122723c94d63SDavid Wu clk_disable_unprepare(bsp_priv->clk_mac_speed); 12287ad269eaSRoger Chen /** 12297ad269eaSRoger Chen * if (!IS_ERR(bsp_priv->clk_mac)) 12307ad269eaSRoger Chen * clk_disable_unprepare(bsp_priv->clk_mac); 12317ad269eaSRoger Chen */ 12327ad269eaSRoger Chen bsp_priv->clk_enabled = false; 12337ad269eaSRoger Chen } 12347ad269eaSRoger Chen } 12357ad269eaSRoger Chen 12367ad269eaSRoger Chen return 0; 12377ad269eaSRoger Chen } 12387ad269eaSRoger Chen 12397ad269eaSRoger Chen static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable) 12407ad269eaSRoger Chen { 12412e12f536SRomain Perier struct regulator *ldo = bsp_priv->regulator; 12427ad269eaSRoger Chen int ret; 12437ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 12447ad269eaSRoger Chen 12453b25528eSChen-Yu Tsai if (!ldo) 12463b25528eSChen-Yu Tsai return 0; 12477ad269eaSRoger Chen 12487ad269eaSRoger Chen if (enable) { 12497ad269eaSRoger Chen ret = regulator_enable(ldo); 12502e12f536SRomain Perier if (ret) 1251d42202dcSRomain Perier dev_err(dev, "fail to enable phy-supply\n"); 12527ad269eaSRoger Chen } else { 12537ad269eaSRoger Chen ret = regulator_disable(ldo); 12542e12f536SRomain Perier if (ret) 1255d42202dcSRomain Perier dev_err(dev, "fail to disable phy-supply\n"); 12567ad269eaSRoger Chen } 12577ad269eaSRoger Chen 12587ad269eaSRoger Chen return 0; 12597ad269eaSRoger Chen } 12607ad269eaSRoger Chen 12610fb98db1SHeiko Stübner static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev, 1262fecd4d7eSDavid Wu struct plat_stmmacenet_data *plat, 126392c2588fSJoachim Eastwood const struct rk_gmac_ops *ops) 12647ad269eaSRoger Chen { 12657ad269eaSRoger Chen struct rk_priv_data *bsp_priv; 12667ad269eaSRoger Chen struct device *dev = &pdev->dev; 12677ad269eaSRoger Chen int ret; 12687ad269eaSRoger Chen const char *strings = NULL; 12697ad269eaSRoger Chen int value; 12707ad269eaSRoger Chen 12717ad269eaSRoger Chen bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL); 12727ad269eaSRoger Chen if (!bsp_priv) 12737ad269eaSRoger Chen return ERR_PTR(-ENOMEM); 12747ad269eaSRoger Chen 12750c65b2b9SAndrew Lunn of_get_phy_mode(dev->of_node, &bsp_priv->phy_iface); 12760fb98db1SHeiko Stübner bsp_priv->ops = ops; 12777ad269eaSRoger Chen 12782e12f536SRomain Perier bsp_priv->regulator = devm_regulator_get_optional(dev, "phy"); 12792e12f536SRomain Perier if (IS_ERR(bsp_priv->regulator)) { 12802e12f536SRomain Perier if (PTR_ERR(bsp_priv->regulator) == -EPROBE_DEFER) { 12812e12f536SRomain Perier dev_err(dev, "phy regulator is not available yet, deferred probing\n"); 12822e12f536SRomain Perier return ERR_PTR(-EPROBE_DEFER); 12832e12f536SRomain Perier } 12842e12f536SRomain Perier dev_err(dev, "no regulator found\n"); 12852e12f536SRomain Perier bsp_priv->regulator = NULL; 12867ad269eaSRoger Chen } 12877ad269eaSRoger Chen 12887ad269eaSRoger Chen ret = of_property_read_string(dev->of_node, "clock_in_out", &strings); 12897ad269eaSRoger Chen if (ret) { 1290d42202dcSRomain Perier dev_err(dev, "Can not read property: clock_in_out.\n"); 12917ad269eaSRoger Chen bsp_priv->clock_input = true; 12927ad269eaSRoger Chen } else { 1293d42202dcSRomain Perier dev_info(dev, "clock input or output? (%s).\n", 1294d42202dcSRomain Perier strings); 12957ad269eaSRoger Chen if (!strcmp(strings, "input")) 12967ad269eaSRoger Chen bsp_priv->clock_input = true; 12977ad269eaSRoger Chen else 12987ad269eaSRoger Chen bsp_priv->clock_input = false; 12997ad269eaSRoger Chen } 13007ad269eaSRoger Chen 13017ad269eaSRoger Chen ret = of_property_read_u32(dev->of_node, "tx_delay", &value); 13027ad269eaSRoger Chen if (ret) { 13037ad269eaSRoger Chen bsp_priv->tx_delay = 0x30; 1304d42202dcSRomain Perier dev_err(dev, "Can not read property: tx_delay."); 1305d42202dcSRomain Perier dev_err(dev, "set tx_delay to 0x%x\n", 1306d42202dcSRomain Perier bsp_priv->tx_delay); 13077ad269eaSRoger Chen } else { 1308d42202dcSRomain Perier dev_info(dev, "TX delay(0x%x).\n", value); 13097ad269eaSRoger Chen bsp_priv->tx_delay = value; 13107ad269eaSRoger Chen } 13117ad269eaSRoger Chen 13127ad269eaSRoger Chen ret = of_property_read_u32(dev->of_node, "rx_delay", &value); 13137ad269eaSRoger Chen if (ret) { 13147ad269eaSRoger Chen bsp_priv->rx_delay = 0x10; 1315d42202dcSRomain Perier dev_err(dev, "Can not read property: rx_delay."); 1316d42202dcSRomain Perier dev_err(dev, "set rx_delay to 0x%x\n", 1317d42202dcSRomain Perier bsp_priv->rx_delay); 13187ad269eaSRoger Chen } else { 1319d42202dcSRomain Perier dev_info(dev, "RX delay(0x%x).\n", value); 13207ad269eaSRoger Chen bsp_priv->rx_delay = value; 13217ad269eaSRoger Chen } 13227ad269eaSRoger Chen 13237ad269eaSRoger Chen bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node, 13247ad269eaSRoger Chen "rockchip,grf"); 13257ad269eaSRoger Chen 1326fecd4d7eSDavid Wu if (plat->phy_node) { 1327fecd4d7eSDavid Wu bsp_priv->integrated_phy = of_property_read_bool(plat->phy_node, 1328fecd4d7eSDavid Wu "phy-is-integrated"); 1329fecd4d7eSDavid Wu if (bsp_priv->integrated_phy) { 1330fecd4d7eSDavid Wu bsp_priv->phy_reset = of_reset_control_get(plat->phy_node, NULL); 1331fecd4d7eSDavid Wu if (IS_ERR(bsp_priv->phy_reset)) { 1332fecd4d7eSDavid Wu dev_err(&pdev->dev, "No PHY reset control found.\n"); 1333fecd4d7eSDavid Wu bsp_priv->phy_reset = NULL; 1334fecd4d7eSDavid Wu } 1335fecd4d7eSDavid Wu } 1336fecd4d7eSDavid Wu } 1337fecd4d7eSDavid Wu dev_info(dev, "integrated PHY? (%s).\n", 1338fecd4d7eSDavid Wu bsp_priv->integrated_phy ? "yes" : "no"); 1339fecd4d7eSDavid Wu 1340fecd4d7eSDavid Wu bsp_priv->pdev = pdev; 134145383f52SRoger Chen 134245383f52SRoger Chen return bsp_priv; 134345383f52SRoger Chen } 134445383f52SRoger Chen 1345*37c80d15SDavid Wu static int rk_gmac_check_ops(struct rk_priv_data *bsp_priv) 1346*37c80d15SDavid Wu { 1347*37c80d15SDavid Wu switch (bsp_priv->phy_iface) { 1348*37c80d15SDavid Wu case PHY_INTERFACE_MODE_RGMII: 1349*37c80d15SDavid Wu case PHY_INTERFACE_MODE_RGMII_ID: 1350*37c80d15SDavid Wu case PHY_INTERFACE_MODE_RGMII_RXID: 1351*37c80d15SDavid Wu case PHY_INTERFACE_MODE_RGMII_TXID: 1352*37c80d15SDavid Wu if (!bsp_priv->ops->set_to_rgmii) 1353*37c80d15SDavid Wu return -EINVAL; 1354*37c80d15SDavid Wu break; 1355*37c80d15SDavid Wu case PHY_INTERFACE_MODE_RMII: 1356*37c80d15SDavid Wu if (!bsp_priv->ops->set_to_rmii) 1357*37c80d15SDavid Wu return -EINVAL; 1358*37c80d15SDavid Wu break; 1359*37c80d15SDavid Wu default: 1360*37c80d15SDavid Wu dev_err(&bsp_priv->pdev->dev, 1361*37c80d15SDavid Wu "unsupported interface %d", bsp_priv->phy_iface); 1362*37c80d15SDavid Wu } 1363*37c80d15SDavid Wu return 0; 1364*37c80d15SDavid Wu } 1365*37c80d15SDavid Wu 136645383f52SRoger Chen static int rk_gmac_powerup(struct rk_priv_data *bsp_priv) 136745383f52SRoger Chen { 136845383f52SRoger Chen int ret; 136945383f52SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 137045383f52SRoger Chen 1371*37c80d15SDavid Wu ret = rk_gmac_check_ops(bsp_priv); 1372*37c80d15SDavid Wu if (ret) 1373*37c80d15SDavid Wu return ret; 1374*37c80d15SDavid Wu 1375f217bfdeSHeiko Stübner ret = gmac_clk_enable(bsp_priv, true); 1376f217bfdeSHeiko Stübner if (ret) 1377f217bfdeSHeiko Stübner return ret; 1378f217bfdeSHeiko Stübner 13797ad269eaSRoger Chen /*rmii or rgmii*/ 1380eaf70ad1SWadim Egorov switch (bsp_priv->phy_iface) { 1381eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII: 1382d42202dcSRomain Perier dev_info(dev, "init for RGMII\n"); 13830fb98db1SHeiko Stübner bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 13840fb98db1SHeiko Stübner bsp_priv->rx_delay); 1385eaf70ad1SWadim Egorov break; 1386eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_ID: 1387eaf70ad1SWadim Egorov dev_info(dev, "init for RGMII_ID\n"); 1388eaf70ad1SWadim Egorov bsp_priv->ops->set_to_rgmii(bsp_priv, 0, 0); 1389eaf70ad1SWadim Egorov break; 1390eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_RXID: 1391eaf70ad1SWadim Egorov dev_info(dev, "init for RGMII_RXID\n"); 1392eaf70ad1SWadim Egorov bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 0); 1393eaf70ad1SWadim Egorov break; 1394eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_TXID: 1395eaf70ad1SWadim Egorov dev_info(dev, "init for RGMII_TXID\n"); 1396eaf70ad1SWadim Egorov bsp_priv->ops->set_to_rgmii(bsp_priv, 0, bsp_priv->rx_delay); 1397eaf70ad1SWadim Egorov break; 1398eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RMII: 1399d42202dcSRomain Perier dev_info(dev, "init for RMII\n"); 14000fb98db1SHeiko Stübner bsp_priv->ops->set_to_rmii(bsp_priv); 1401eaf70ad1SWadim Egorov break; 1402eaf70ad1SWadim Egorov default: 1403d42202dcSRomain Perier dev_err(dev, "NO interface defined!\n"); 14047ad269eaSRoger Chen } 14057ad269eaSRoger Chen 14067ad269eaSRoger Chen ret = phy_power_on(bsp_priv, true); 1407c69c29a1SAlexey Khoroshilov if (ret) { 1408c69c29a1SAlexey Khoroshilov gmac_clk_enable(bsp_priv, false); 14097ad269eaSRoger Chen return ret; 1410c69c29a1SAlexey Khoroshilov } 14117ad269eaSRoger Chen 14122c896fb0SDavid Wu pm_runtime_enable(dev); 14132c896fb0SDavid Wu pm_runtime_get_sync(dev); 14142c896fb0SDavid Wu 1415fecd4d7eSDavid Wu if (bsp_priv->integrated_phy) 1416fecd4d7eSDavid Wu rk_gmac_integrated_phy_powerup(bsp_priv); 1417fecd4d7eSDavid Wu 14187ad269eaSRoger Chen return 0; 14197ad269eaSRoger Chen } 14207ad269eaSRoger Chen 1421229666c1SVincent Palatin static void rk_gmac_powerdown(struct rk_priv_data *gmac) 14227ad269eaSRoger Chen { 14232c896fb0SDavid Wu struct device *dev = &gmac->pdev->dev; 14242c896fb0SDavid Wu 1425fecd4d7eSDavid Wu if (gmac->integrated_phy) 1426fecd4d7eSDavid Wu rk_gmac_integrated_phy_powerdown(gmac); 1427fecd4d7eSDavid Wu 14282c896fb0SDavid Wu pm_runtime_put_sync(dev); 14292c896fb0SDavid Wu pm_runtime_disable(dev); 14302c896fb0SDavid Wu 14317ad269eaSRoger Chen phy_power_on(gmac, false); 14327ad269eaSRoger Chen gmac_clk_enable(gmac, false); 14337ad269eaSRoger Chen } 14347ad269eaSRoger Chen 14357ad269eaSRoger Chen static void rk_fix_speed(void *priv, unsigned int speed) 14367ad269eaSRoger Chen { 14377ad269eaSRoger Chen struct rk_priv_data *bsp_priv = priv; 14387ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 14397ad269eaSRoger Chen 1440eaf70ad1SWadim Egorov switch (bsp_priv->phy_iface) { 1441eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII: 1442eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_ID: 1443eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_RXID: 1444eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_TXID: 1445*37c80d15SDavid Wu if (bsp_priv->ops->set_rgmii_speed) 14460fb98db1SHeiko Stübner bsp_priv->ops->set_rgmii_speed(bsp_priv, speed); 1447eaf70ad1SWadim Egorov break; 1448eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RMII: 1449*37c80d15SDavid Wu if (bsp_priv->ops->set_rmii_speed) 14500fb98db1SHeiko Stübner bsp_priv->ops->set_rmii_speed(bsp_priv, speed); 1451eaf70ad1SWadim Egorov break; 1452eaf70ad1SWadim Egorov default: 14537ad269eaSRoger Chen dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface); 14547ad269eaSRoger Chen } 1455eaf70ad1SWadim Egorov } 14567ad269eaSRoger Chen 145727ffefd2SJoachim Eastwood static int rk_gmac_probe(struct platform_device *pdev) 145827ffefd2SJoachim Eastwood { 145927ffefd2SJoachim Eastwood struct plat_stmmacenet_data *plat_dat; 146027ffefd2SJoachim Eastwood struct stmmac_resources stmmac_res; 1461f529f182SJoachim Eastwood const struct rk_gmac_ops *data; 146227ffefd2SJoachim Eastwood int ret; 146327ffefd2SJoachim Eastwood 1464149adeddSJoachim Eastwood data = of_device_get_match_data(&pdev->dev); 1465149adeddSJoachim Eastwood if (!data) { 1466149adeddSJoachim Eastwood dev_err(&pdev->dev, "no of match data provided\n"); 1467149adeddSJoachim Eastwood return -EINVAL; 1468149adeddSJoachim Eastwood } 1469149adeddSJoachim Eastwood 147027ffefd2SJoachim Eastwood ret = stmmac_get_platform_resources(pdev, &stmmac_res); 147127ffefd2SJoachim Eastwood if (ret) 147227ffefd2SJoachim Eastwood return ret; 147327ffefd2SJoachim Eastwood 147483216e39SMichael Walle plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac); 147527ffefd2SJoachim Eastwood if (IS_ERR(plat_dat)) 147627ffefd2SJoachim Eastwood return PTR_ERR(plat_dat); 147727ffefd2SJoachim Eastwood 1478d6b06251SEzequiel Garcia /* If the stmmac is not already selected as gmac4, 1479d6b06251SEzequiel Garcia * then make sure we fallback to gmac. 1480d6b06251SEzequiel Garcia */ 1481d6b06251SEzequiel Garcia if (!plat_dat->has_gmac4) 148227ffefd2SJoachim Eastwood plat_dat->has_gmac = true; 148327ffefd2SJoachim Eastwood plat_dat->fix_mac_speed = rk_fix_speed; 148427ffefd2SJoachim Eastwood 1485fecd4d7eSDavid Wu plat_dat->bsp_priv = rk_gmac_setup(pdev, plat_dat, data); 1486d2ed0a77SJohan Hovold if (IS_ERR(plat_dat->bsp_priv)) { 1487d2ed0a77SJohan Hovold ret = PTR_ERR(plat_dat->bsp_priv); 1488d2ed0a77SJohan Hovold goto err_remove_config_dt; 1489d2ed0a77SJohan Hovold } 149027ffefd2SJoachim Eastwood 1491fecd4d7eSDavid Wu ret = rk_gmac_clk_init(plat_dat); 1492fecd4d7eSDavid Wu if (ret) 14939de9aa48SEmil Renner Berthing goto err_remove_config_dt; 1494fecd4d7eSDavid Wu 149507a5e769SJoachim Eastwood ret = rk_gmac_powerup(plat_dat->bsp_priv); 149627ffefd2SJoachim Eastwood if (ret) 1497d2ed0a77SJohan Hovold goto err_remove_config_dt; 149827ffefd2SJoachim Eastwood 14992d222656SJohan Hovold ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); 15002d222656SJohan Hovold if (ret) 15012745529aSDavid S. Miller goto err_gmac_powerdown; 15022d222656SJohan Hovold 15032d222656SJohan Hovold return 0; 15042d222656SJohan Hovold 15052745529aSDavid S. Miller err_gmac_powerdown: 15062745529aSDavid S. Miller rk_gmac_powerdown(plat_dat->bsp_priv); 1507d2ed0a77SJohan Hovold err_remove_config_dt: 1508d2ed0a77SJohan Hovold stmmac_remove_config_dt(pdev, plat_dat); 15092d222656SJohan Hovold 15102d222656SJohan Hovold return ret; 151127ffefd2SJoachim Eastwood } 151227ffefd2SJoachim Eastwood 15130de8c4c9SJoachim Eastwood static int rk_gmac_remove(struct platform_device *pdev) 15140de8c4c9SJoachim Eastwood { 15150de8c4c9SJoachim Eastwood struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(&pdev->dev); 15160de8c4c9SJoachim Eastwood int ret = stmmac_dvr_remove(&pdev->dev); 15170de8c4c9SJoachim Eastwood 15180de8c4c9SJoachim Eastwood rk_gmac_powerdown(bsp_priv); 15190de8c4c9SJoachim Eastwood 15200de8c4c9SJoachim Eastwood return ret; 15210de8c4c9SJoachim Eastwood } 15220de8c4c9SJoachim Eastwood 15235619468aSJoachim Eastwood #ifdef CONFIG_PM_SLEEP 15245619468aSJoachim Eastwood static int rk_gmac_suspend(struct device *dev) 15255619468aSJoachim Eastwood { 15265619468aSJoachim Eastwood struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev); 15275619468aSJoachim Eastwood int ret = stmmac_suspend(dev); 15285619468aSJoachim Eastwood 15295619468aSJoachim Eastwood /* Keep the PHY up if we use Wake-on-Lan. */ 15305619468aSJoachim Eastwood if (!device_may_wakeup(dev)) { 15315619468aSJoachim Eastwood rk_gmac_powerdown(bsp_priv); 15325619468aSJoachim Eastwood bsp_priv->suspended = true; 15335619468aSJoachim Eastwood } 15345619468aSJoachim Eastwood 15355619468aSJoachim Eastwood return ret; 15365619468aSJoachim Eastwood } 15375619468aSJoachim Eastwood 15385619468aSJoachim Eastwood static int rk_gmac_resume(struct device *dev) 15395619468aSJoachim Eastwood { 15405619468aSJoachim Eastwood struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev); 15415619468aSJoachim Eastwood 15425619468aSJoachim Eastwood /* The PHY was up for Wake-on-Lan. */ 15435619468aSJoachim Eastwood if (bsp_priv->suspended) { 15445619468aSJoachim Eastwood rk_gmac_powerup(bsp_priv); 15455619468aSJoachim Eastwood bsp_priv->suspended = false; 15465619468aSJoachim Eastwood } 15475619468aSJoachim Eastwood 15485619468aSJoachim Eastwood return stmmac_resume(dev); 15495619468aSJoachim Eastwood } 15505619468aSJoachim Eastwood #endif /* CONFIG_PM_SLEEP */ 15515619468aSJoachim Eastwood 15525619468aSJoachim Eastwood static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume); 15535619468aSJoachim Eastwood 1554e0fb4013SJoachim Eastwood static const struct of_device_id rk_gmac_dwmac_match[] = { 155523c94d63SDavid Wu { .compatible = "rockchip,px30-gmac", .data = &px30_ops }, 155605946876SDavid Wu { .compatible = "rockchip,rk3128-gmac", .data = &rk3128_ops }, 1557e7ffd812SXing Zheng { .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops }, 1558f529f182SJoachim Eastwood { .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops }, 1559b4ac9456STobias Schramm { .compatible = "rockchip,rk3308-gmac", .data = &rk3308_ops }, 1560d4ff816eSdavid.wu { .compatible = "rockchip,rk3328-gmac", .data = &rk3328_ops }, 1561ba289af8SRoger Chen { .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops }, 1562f529f182SJoachim Eastwood { .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops }, 1563ba289af8SRoger Chen { .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops }, 156489c9c163SDavid Wu { .compatible = "rockchip,rv1108-gmac", .data = &rv1108_ops }, 1565e0fb4013SJoachim Eastwood { } 1566e0fb4013SJoachim Eastwood }; 1567e0fb4013SJoachim Eastwood MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match); 1568e0fb4013SJoachim Eastwood 1569e0fb4013SJoachim Eastwood static struct platform_driver rk_gmac_dwmac_driver = { 157027ffefd2SJoachim Eastwood .probe = rk_gmac_probe, 15710de8c4c9SJoachim Eastwood .remove = rk_gmac_remove, 1572e0fb4013SJoachim Eastwood .driver = { 1573e0fb4013SJoachim Eastwood .name = "rk_gmac-dwmac", 15745619468aSJoachim Eastwood .pm = &rk_gmac_pm_ops, 1575e0fb4013SJoachim Eastwood .of_match_table = rk_gmac_dwmac_match, 1576e0fb4013SJoachim Eastwood }, 1577e0fb4013SJoachim Eastwood }; 1578e0fb4013SJoachim Eastwood module_platform_driver(rk_gmac_dwmac_driver); 1579e0fb4013SJoachim Eastwood 1580e0fb4013SJoachim Eastwood MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>"); 1581e0fb4013SJoachim Eastwood MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer"); 1582e0fb4013SJoachim Eastwood MODULE_LICENSE("GPL"); 1583