1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 27ad269eaSRoger Chen /** 3d0ea5cbdSJesse Brandeburg * DOC: dwmac-rk.c - Rockchip RK3288 DWMAC specific glue layer 47ad269eaSRoger Chen * 57ad269eaSRoger Chen * Copyright (C) 2014 Chen-Zhi (Roger Chen) 67ad269eaSRoger Chen * 77ad269eaSRoger Chen * Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com> 87ad269eaSRoger Chen */ 97ad269eaSRoger Chen 107ad269eaSRoger Chen #include <linux/stmmac.h> 117ad269eaSRoger Chen #include <linux/bitops.h> 127ad269eaSRoger Chen #include <linux/clk.h> 137ad269eaSRoger Chen #include <linux/phy.h> 147ad269eaSRoger Chen #include <linux/of_net.h> 157ad269eaSRoger Chen #include <linux/gpio.h> 16e0fb4013SJoachim Eastwood #include <linux/module.h> 177ad269eaSRoger Chen #include <linux/of_gpio.h> 187ad269eaSRoger Chen #include <linux/of_device.h> 19e0fb4013SJoachim Eastwood #include <linux/platform_device.h> 207ad269eaSRoger Chen #include <linux/regulator/consumer.h> 217ad269eaSRoger Chen #include <linux/delay.h> 227ad269eaSRoger Chen #include <linux/mfd/syscon.h> 237ad269eaSRoger Chen #include <linux/regmap.h> 24aec3f415SPunit Agrawal #include <linux/pm_runtime.h> 257ad269eaSRoger Chen 26e0fb4013SJoachim Eastwood #include "stmmac_platform.h" 27e0fb4013SJoachim Eastwood 280fb98db1SHeiko Stübner struct rk_priv_data; 290fb98db1SHeiko Stübner struct rk_gmac_ops { 300fb98db1SHeiko Stübner void (*set_to_rgmii)(struct rk_priv_data *bsp_priv, 310fb98db1SHeiko Stübner int tx_delay, int rx_delay); 320fb98db1SHeiko Stübner void (*set_to_rmii)(struct rk_priv_data *bsp_priv); 330fb98db1SHeiko Stübner void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed); 340fb98db1SHeiko Stübner void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed); 35fecd4d7eSDavid Wu void (*integrated_phy_powerup)(struct rk_priv_data *bsp_priv); 36*0546b224SJohn Keeping bool regs_valid; 373bb3d6b1SDavid Wu u32 regs[]; 380fb98db1SHeiko Stübner }; 390fb98db1SHeiko Stübner 407ad269eaSRoger Chen struct rk_priv_data { 417ad269eaSRoger Chen struct platform_device *pdev; 420c65b2b9SAndrew Lunn phy_interface_t phy_iface; 433bb3d6b1SDavid Wu int id; 442e12f536SRomain Perier struct regulator *regulator; 45229666c1SVincent Palatin bool suspended; 4692c2588fSJoachim Eastwood const struct rk_gmac_ops *ops; 477ad269eaSRoger Chen 487ad269eaSRoger Chen bool clk_enabled; 497ad269eaSRoger Chen bool clock_input; 50fecd4d7eSDavid Wu bool integrated_phy; 517ad269eaSRoger Chen 527ad269eaSRoger Chen struct clk *clk_mac; 537ad269eaSRoger Chen struct clk *gmac_clkin; 547ad269eaSRoger Chen struct clk *mac_clk_rx; 557ad269eaSRoger Chen struct clk *mac_clk_tx; 567ad269eaSRoger Chen struct clk *clk_mac_ref; 577ad269eaSRoger Chen struct clk *clk_mac_refout; 5823c94d63SDavid Wu struct clk *clk_mac_speed; 597ad269eaSRoger Chen struct clk *aclk_mac; 607ad269eaSRoger Chen struct clk *pclk_mac; 61fecd4d7eSDavid Wu struct clk *clk_phy; 62fecd4d7eSDavid Wu 63fecd4d7eSDavid Wu struct reset_control *phy_reset; 647ad269eaSRoger Chen 657ad269eaSRoger Chen int tx_delay; 667ad269eaSRoger Chen int rx_delay; 677ad269eaSRoger Chen 687ad269eaSRoger Chen struct regmap *grf; 697ad269eaSRoger Chen }; 707ad269eaSRoger Chen 717ad269eaSRoger Chen #define HIWORD_UPDATE(val, mask, shift) \ 727ad269eaSRoger Chen ((val) << (shift) | (mask) << ((shift) + 16)) 737ad269eaSRoger Chen 747ad269eaSRoger Chen #define GRF_BIT(nr) (BIT(nr) | BIT(nr+16)) 757ad269eaSRoger Chen #define GRF_CLR_BIT(nr) (BIT(nr+16)) 767ad269eaSRoger Chen 77eaf70ad1SWadim Egorov #define DELAY_ENABLE(soc, tx, rx) \ 78eaf70ad1SWadim Egorov (((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \ 79eaf70ad1SWadim Egorov ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE)) 80eaf70ad1SWadim Egorov 8123c94d63SDavid Wu #define PX30_GRF_GMAC_CON1 0x0904 8223c94d63SDavid Wu 8323c94d63SDavid Wu /* PX30_GRF_GMAC_CON1 */ 8423c94d63SDavid Wu #define PX30_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \ 8523c94d63SDavid Wu GRF_BIT(6)) 8623c94d63SDavid Wu #define PX30_GMAC_SPEED_10M GRF_CLR_BIT(2) 8723c94d63SDavid Wu #define PX30_GMAC_SPEED_100M GRF_BIT(2) 8823c94d63SDavid Wu 8923c94d63SDavid Wu static void px30_set_to_rmii(struct rk_priv_data *bsp_priv) 9023c94d63SDavid Wu { 9123c94d63SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 9223c94d63SDavid Wu 9323c94d63SDavid Wu if (IS_ERR(bsp_priv->grf)) { 9423c94d63SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 9523c94d63SDavid Wu return; 9623c94d63SDavid Wu } 9723c94d63SDavid Wu 9823c94d63SDavid Wu regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1, 9923c94d63SDavid Wu PX30_GMAC_PHY_INTF_SEL_RMII); 10023c94d63SDavid Wu } 10123c94d63SDavid Wu 10223c94d63SDavid Wu static void px30_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 10323c94d63SDavid Wu { 10423c94d63SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 10523c94d63SDavid Wu int ret; 10623c94d63SDavid Wu 10723c94d63SDavid Wu if (IS_ERR(bsp_priv->clk_mac_speed)) { 10823c94d63SDavid Wu dev_err(dev, "%s: Missing clk_mac_speed clock\n", __func__); 10923c94d63SDavid Wu return; 11023c94d63SDavid Wu } 11123c94d63SDavid Wu 11223c94d63SDavid Wu if (speed == 10) { 11323c94d63SDavid Wu regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1, 11423c94d63SDavid Wu PX30_GMAC_SPEED_10M); 11523c94d63SDavid Wu 11623c94d63SDavid Wu ret = clk_set_rate(bsp_priv->clk_mac_speed, 2500000); 11723c94d63SDavid Wu if (ret) 11823c94d63SDavid Wu dev_err(dev, "%s: set clk_mac_speed rate 2500000 failed: %d\n", 11923c94d63SDavid Wu __func__, ret); 12023c94d63SDavid Wu } else if (speed == 100) { 12123c94d63SDavid Wu regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1, 12223c94d63SDavid Wu PX30_GMAC_SPEED_100M); 12323c94d63SDavid Wu 12423c94d63SDavid Wu ret = clk_set_rate(bsp_priv->clk_mac_speed, 25000000); 12523c94d63SDavid Wu if (ret) 12623c94d63SDavid Wu dev_err(dev, "%s: set clk_mac_speed rate 25000000 failed: %d\n", 12723c94d63SDavid Wu __func__, ret); 12823c94d63SDavid Wu 12923c94d63SDavid Wu } else { 13023c94d63SDavid Wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 13123c94d63SDavid Wu } 13223c94d63SDavid Wu } 13323c94d63SDavid Wu 13423c94d63SDavid Wu static const struct rk_gmac_ops px30_ops = { 13523c94d63SDavid Wu .set_to_rmii = px30_set_to_rmii, 13623c94d63SDavid Wu .set_rmii_speed = px30_set_rmii_speed, 13723c94d63SDavid Wu }; 13823c94d63SDavid Wu 13905946876SDavid Wu #define RK3128_GRF_MAC_CON0 0x0168 14005946876SDavid Wu #define RK3128_GRF_MAC_CON1 0x016c 14105946876SDavid Wu 14205946876SDavid Wu /* RK3128_GRF_MAC_CON0 */ 14305946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_ENABLE GRF_BIT(14) 14405946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14) 14505946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 14605946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 14705946876SDavid Wu #define RK3128_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 14805946876SDavid Wu #define RK3128_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 14905946876SDavid Wu 15005946876SDavid Wu /* RK3128_GRF_MAC_CON1 */ 15105946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RGMII \ 15205946876SDavid Wu (GRF_BIT(6) | GRF_CLR_BIT(7) | GRF_CLR_BIT(8)) 15305946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RMII \ 15405946876SDavid Wu (GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | GRF_BIT(8)) 15505946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL GRF_BIT(9) 15605946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(9) 15705946876SDavid Wu #define RK3128_GMAC_SPEED_10M GRF_CLR_BIT(10) 15805946876SDavid Wu #define RK3128_GMAC_SPEED_100M GRF_BIT(10) 15905946876SDavid Wu #define RK3128_GMAC_RMII_CLK_25M GRF_BIT(11) 16005946876SDavid Wu #define RK3128_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(11) 16105946876SDavid Wu #define RK3128_GMAC_CLK_125M (GRF_CLR_BIT(12) | GRF_CLR_BIT(13)) 16205946876SDavid Wu #define RK3128_GMAC_CLK_25M (GRF_BIT(12) | GRF_BIT(13)) 16305946876SDavid Wu #define RK3128_GMAC_CLK_2_5M (GRF_CLR_BIT(12) | GRF_BIT(13)) 16405946876SDavid Wu #define RK3128_GMAC_RMII_MODE GRF_BIT(14) 16505946876SDavid Wu #define RK3128_GMAC_RMII_MODE_CLR GRF_CLR_BIT(14) 16605946876SDavid Wu 16705946876SDavid Wu static void rk3128_set_to_rgmii(struct rk_priv_data *bsp_priv, 16805946876SDavid Wu int tx_delay, int rx_delay) 16905946876SDavid Wu { 17005946876SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 17105946876SDavid Wu 17205946876SDavid Wu if (IS_ERR(bsp_priv->grf)) { 17305946876SDavid Wu dev_err(dev, "Missing rockchip,grf property\n"); 17405946876SDavid Wu return; 17505946876SDavid Wu } 17605946876SDavid Wu 17705946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 17805946876SDavid Wu RK3128_GMAC_PHY_INTF_SEL_RGMII | 17905946876SDavid Wu RK3128_GMAC_RMII_MODE_CLR); 18005946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON0, 18105946876SDavid Wu DELAY_ENABLE(RK3128, tx_delay, rx_delay) | 18205946876SDavid Wu RK3128_GMAC_CLK_RX_DL_CFG(rx_delay) | 18305946876SDavid Wu RK3128_GMAC_CLK_TX_DL_CFG(tx_delay)); 18405946876SDavid Wu } 18505946876SDavid Wu 18605946876SDavid Wu static void rk3128_set_to_rmii(struct rk_priv_data *bsp_priv) 18705946876SDavid Wu { 18805946876SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 18905946876SDavid Wu 19005946876SDavid Wu if (IS_ERR(bsp_priv->grf)) { 19105946876SDavid Wu dev_err(dev, "Missing rockchip,grf property\n"); 19205946876SDavid Wu return; 19305946876SDavid Wu } 19405946876SDavid Wu 19505946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 19605946876SDavid Wu RK3128_GMAC_PHY_INTF_SEL_RMII | RK3128_GMAC_RMII_MODE); 19705946876SDavid Wu } 19805946876SDavid Wu 19905946876SDavid Wu static void rk3128_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 20005946876SDavid Wu { 20105946876SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 20205946876SDavid Wu 20305946876SDavid Wu if (IS_ERR(bsp_priv->grf)) { 20405946876SDavid Wu dev_err(dev, "Missing rockchip,grf property\n"); 20505946876SDavid Wu return; 20605946876SDavid Wu } 20705946876SDavid Wu 20805946876SDavid Wu if (speed == 10) 20905946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 21005946876SDavid Wu RK3128_GMAC_CLK_2_5M); 21105946876SDavid Wu else if (speed == 100) 21205946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 21305946876SDavid Wu RK3128_GMAC_CLK_25M); 21405946876SDavid Wu else if (speed == 1000) 21505946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 21605946876SDavid Wu RK3128_GMAC_CLK_125M); 21705946876SDavid Wu else 21805946876SDavid Wu dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 21905946876SDavid Wu } 22005946876SDavid Wu 22105946876SDavid Wu static void rk3128_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 22205946876SDavid Wu { 22305946876SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 22405946876SDavid Wu 22505946876SDavid Wu if (IS_ERR(bsp_priv->grf)) { 22605946876SDavid Wu dev_err(dev, "Missing rockchip,grf property\n"); 22705946876SDavid Wu return; 22805946876SDavid Wu } 22905946876SDavid Wu 23005946876SDavid Wu if (speed == 10) { 23105946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 23205946876SDavid Wu RK3128_GMAC_RMII_CLK_2_5M | 23305946876SDavid Wu RK3128_GMAC_SPEED_10M); 23405946876SDavid Wu } else if (speed == 100) { 23505946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 23605946876SDavid Wu RK3128_GMAC_RMII_CLK_25M | 23705946876SDavid Wu RK3128_GMAC_SPEED_100M); 23805946876SDavid Wu } else { 23905946876SDavid Wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 24005946876SDavid Wu } 24105946876SDavid Wu } 24205946876SDavid Wu 24305946876SDavid Wu static const struct rk_gmac_ops rk3128_ops = { 24405946876SDavid Wu .set_to_rgmii = rk3128_set_to_rgmii, 24505946876SDavid Wu .set_to_rmii = rk3128_set_to_rmii, 24605946876SDavid Wu .set_rgmii_speed = rk3128_set_rgmii_speed, 24705946876SDavid Wu .set_rmii_speed = rk3128_set_rmii_speed, 24805946876SDavid Wu }; 24905946876SDavid Wu 250e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON0 0x0900 251e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON1 0x0904 252e7ffd812SXing Zheng 2536fa12c78SDavid Wu #define RK3228_GRF_CON_MUX 0x50 2546fa12c78SDavid Wu 255e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON0 */ 256e7ffd812SXing Zheng #define RK3228_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 257e7ffd812SXing Zheng #define RK3228_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 258e7ffd812SXing Zheng 259e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON1 */ 260e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RGMII \ 261e7ffd812SXing Zheng (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6)) 262e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RMII \ 263e7ffd812SXing Zheng (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6)) 264e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL GRF_BIT(3) 265e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 266e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_10M GRF_CLR_BIT(2) 267e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_100M GRF_BIT(2) 268e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_25M GRF_BIT(7) 269e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7) 270e7ffd812SXing Zheng #define RK3228_GMAC_CLK_125M (GRF_CLR_BIT(8) | GRF_CLR_BIT(9)) 271e7ffd812SXing Zheng #define RK3228_GMAC_CLK_25M (GRF_BIT(8) | GRF_BIT(9)) 272e7ffd812SXing Zheng #define RK3228_GMAC_CLK_2_5M (GRF_CLR_BIT(8) | GRF_BIT(9)) 273e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE GRF_BIT(10) 274e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE_CLR GRF_CLR_BIT(10) 275e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0) 276e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0) 277e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1) 278e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(1) 279e7ffd812SXing Zheng 2806fa12c78SDavid Wu /* RK3228_GRF_COM_MUX */ 2816fa12c78SDavid Wu #define RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY GRF_BIT(15) 2826fa12c78SDavid Wu 283e7ffd812SXing Zheng static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv, 284e7ffd812SXing Zheng int tx_delay, int rx_delay) 285e7ffd812SXing Zheng { 286e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 287e7ffd812SXing Zheng 288e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 289e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 290e7ffd812SXing Zheng return; 291e7ffd812SXing Zheng } 292e7ffd812SXing Zheng 293e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 294e7ffd812SXing Zheng RK3228_GMAC_PHY_INTF_SEL_RGMII | 295e7ffd812SXing Zheng RK3228_GMAC_RMII_MODE_CLR | 296eaf70ad1SWadim Egorov DELAY_ENABLE(RK3228, tx_delay, rx_delay)); 297e7ffd812SXing Zheng 298e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON0, 299e7ffd812SXing Zheng RK3228_GMAC_CLK_RX_DL_CFG(rx_delay) | 300e7ffd812SXing Zheng RK3228_GMAC_CLK_TX_DL_CFG(tx_delay)); 301e7ffd812SXing Zheng } 302e7ffd812SXing Zheng 303e7ffd812SXing Zheng static void rk3228_set_to_rmii(struct rk_priv_data *bsp_priv) 304e7ffd812SXing Zheng { 305e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 306e7ffd812SXing Zheng 307e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 308e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 309e7ffd812SXing Zheng return; 310e7ffd812SXing Zheng } 311e7ffd812SXing Zheng 312e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 313e7ffd812SXing Zheng RK3228_GMAC_PHY_INTF_SEL_RMII | 314e7ffd812SXing Zheng RK3228_GMAC_RMII_MODE); 315e7ffd812SXing Zheng 316e7ffd812SXing Zheng /* set MAC to RMII mode */ 317e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, GRF_BIT(11)); 318e7ffd812SXing Zheng } 319e7ffd812SXing Zheng 320e7ffd812SXing Zheng static void rk3228_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 321e7ffd812SXing Zheng { 322e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 323e7ffd812SXing Zheng 324e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 325e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 326e7ffd812SXing Zheng return; 327e7ffd812SXing Zheng } 328e7ffd812SXing Zheng 329e7ffd812SXing Zheng if (speed == 10) 330e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 331e7ffd812SXing Zheng RK3228_GMAC_CLK_2_5M); 332e7ffd812SXing Zheng else if (speed == 100) 333e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 334e7ffd812SXing Zheng RK3228_GMAC_CLK_25M); 335e7ffd812SXing Zheng else if (speed == 1000) 336e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 337e7ffd812SXing Zheng RK3228_GMAC_CLK_125M); 338e7ffd812SXing Zheng else 339e7ffd812SXing Zheng dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 340e7ffd812SXing Zheng } 341e7ffd812SXing Zheng 342e7ffd812SXing Zheng static void rk3228_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 343e7ffd812SXing Zheng { 344e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 345e7ffd812SXing Zheng 346e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 347e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 348e7ffd812SXing Zheng return; 349e7ffd812SXing Zheng } 350e7ffd812SXing Zheng 351e7ffd812SXing Zheng if (speed == 10) 352e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 353e7ffd812SXing Zheng RK3228_GMAC_RMII_CLK_2_5M | 354e7ffd812SXing Zheng RK3228_GMAC_SPEED_10M); 355e7ffd812SXing Zheng else if (speed == 100) 356e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 357e7ffd812SXing Zheng RK3228_GMAC_RMII_CLK_25M | 358e7ffd812SXing Zheng RK3228_GMAC_SPEED_100M); 359e7ffd812SXing Zheng else 360e7ffd812SXing Zheng dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 361e7ffd812SXing Zheng } 362e7ffd812SXing Zheng 3636fa12c78SDavid Wu static void rk3228_integrated_phy_powerup(struct rk_priv_data *priv) 3646fa12c78SDavid Wu { 3656fa12c78SDavid Wu regmap_write(priv->grf, RK3228_GRF_CON_MUX, 3666fa12c78SDavid Wu RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY); 3676fa12c78SDavid Wu } 3686fa12c78SDavid Wu 369e7ffd812SXing Zheng static const struct rk_gmac_ops rk3228_ops = { 370e7ffd812SXing Zheng .set_to_rgmii = rk3228_set_to_rgmii, 371e7ffd812SXing Zheng .set_to_rmii = rk3228_set_to_rmii, 372e7ffd812SXing Zheng .set_rgmii_speed = rk3228_set_rgmii_speed, 373e7ffd812SXing Zheng .set_rmii_speed = rk3228_set_rmii_speed, 3746fa12c78SDavid Wu .integrated_phy_powerup = rk3228_integrated_phy_powerup, 375e7ffd812SXing Zheng }; 376e7ffd812SXing Zheng 3777ad269eaSRoger Chen #define RK3288_GRF_SOC_CON1 0x0248 3787ad269eaSRoger Chen #define RK3288_GRF_SOC_CON3 0x0250 3797ad269eaSRoger Chen 3807ad269eaSRoger Chen /*RK3288_GRF_SOC_CON1*/ 3810fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(6) | GRF_CLR_BIT(7) | \ 3820fb98db1SHeiko Stübner GRF_CLR_BIT(8)) 3830fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | \ 3840fb98db1SHeiko Stübner GRF_BIT(8)) 3850fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL GRF_BIT(9) 3860fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(9) 3870fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_10M GRF_CLR_BIT(10) 3880fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_100M GRF_BIT(10) 3890fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_25M GRF_BIT(11) 3900fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(11) 3910fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_125M (GRF_CLR_BIT(12) | GRF_CLR_BIT(13)) 3920fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_25M (GRF_BIT(12) | GRF_BIT(13)) 3930fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_2_5M (GRF_CLR_BIT(12) | GRF_BIT(13)) 3940fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE GRF_BIT(14) 3950fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE_CLR GRF_CLR_BIT(14) 3967ad269eaSRoger Chen 3977ad269eaSRoger Chen /*RK3288_GRF_SOC_CON3*/ 3980fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_ENABLE GRF_BIT(14) 3990fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14) 4000fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 4010fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 4020fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 4030fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 4047ad269eaSRoger Chen 4050fb98db1SHeiko Stübner static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv, 4067ad269eaSRoger Chen int tx_delay, int rx_delay) 4077ad269eaSRoger Chen { 4087ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 4097ad269eaSRoger Chen 4107ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 411d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 4127ad269eaSRoger Chen return; 4137ad269eaSRoger Chen } 4147ad269eaSRoger Chen 4157ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4160fb98db1SHeiko Stübner RK3288_GMAC_PHY_INTF_SEL_RGMII | 4170fb98db1SHeiko Stübner RK3288_GMAC_RMII_MODE_CLR); 4187ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3, 419eaf70ad1SWadim Egorov DELAY_ENABLE(RK3288, tx_delay, rx_delay) | 4200fb98db1SHeiko Stübner RK3288_GMAC_CLK_RX_DL_CFG(rx_delay) | 4210fb98db1SHeiko Stübner RK3288_GMAC_CLK_TX_DL_CFG(tx_delay)); 4227ad269eaSRoger Chen } 4237ad269eaSRoger Chen 4240fb98db1SHeiko Stübner static void rk3288_set_to_rmii(struct rk_priv_data *bsp_priv) 4257ad269eaSRoger Chen { 4267ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 4277ad269eaSRoger Chen 4287ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 429d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 4307ad269eaSRoger Chen return; 4317ad269eaSRoger Chen } 4327ad269eaSRoger Chen 4337ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4340fb98db1SHeiko Stübner RK3288_GMAC_PHY_INTF_SEL_RMII | RK3288_GMAC_RMII_MODE); 4357ad269eaSRoger Chen } 4367ad269eaSRoger Chen 4370fb98db1SHeiko Stübner static void rk3288_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 4387ad269eaSRoger Chen { 4397ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 4407ad269eaSRoger Chen 4417ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 442d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 4437ad269eaSRoger Chen return; 4447ad269eaSRoger Chen } 4457ad269eaSRoger Chen 4467ad269eaSRoger Chen if (speed == 10) 4470fb98db1SHeiko Stübner regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4480fb98db1SHeiko Stübner RK3288_GMAC_CLK_2_5M); 4497ad269eaSRoger Chen else if (speed == 100) 4500fb98db1SHeiko Stübner regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4510fb98db1SHeiko Stübner RK3288_GMAC_CLK_25M); 4527ad269eaSRoger Chen else if (speed == 1000) 4530fb98db1SHeiko Stübner regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4540fb98db1SHeiko Stübner RK3288_GMAC_CLK_125M); 4557ad269eaSRoger Chen else 4567ad269eaSRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 4577ad269eaSRoger Chen } 4587ad269eaSRoger Chen 4590fb98db1SHeiko Stübner static void rk3288_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 4607ad269eaSRoger Chen { 4617ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 4627ad269eaSRoger Chen 4637ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 464d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 4657ad269eaSRoger Chen return; 4667ad269eaSRoger Chen } 4677ad269eaSRoger Chen 4687ad269eaSRoger Chen if (speed == 10) { 4697ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4700fb98db1SHeiko Stübner RK3288_GMAC_RMII_CLK_2_5M | 4710fb98db1SHeiko Stübner RK3288_GMAC_SPEED_10M); 4727ad269eaSRoger Chen } else if (speed == 100) { 4737ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4740fb98db1SHeiko Stübner RK3288_GMAC_RMII_CLK_25M | 4750fb98db1SHeiko Stübner RK3288_GMAC_SPEED_100M); 4767ad269eaSRoger Chen } else { 4777ad269eaSRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 4787ad269eaSRoger Chen } 4797ad269eaSRoger Chen } 4807ad269eaSRoger Chen 48192c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3288_ops = { 4820fb98db1SHeiko Stübner .set_to_rgmii = rk3288_set_to_rgmii, 4830fb98db1SHeiko Stübner .set_to_rmii = rk3288_set_to_rmii, 4840fb98db1SHeiko Stübner .set_rgmii_speed = rk3288_set_rgmii_speed, 4850fb98db1SHeiko Stübner .set_rmii_speed = rk3288_set_rmii_speed, 4860fb98db1SHeiko Stübner }; 4870fb98db1SHeiko Stübner 488b4ac9456STobias Schramm #define RK3308_GRF_MAC_CON0 0x04a0 489b4ac9456STobias Schramm 490b4ac9456STobias Schramm /* RK3308_GRF_MAC_CON0 */ 491b4ac9456STobias Schramm #define RK3308_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(2) | GRF_CLR_BIT(3) | \ 492b4ac9456STobias Schramm GRF_BIT(4)) 493b4ac9456STobias Schramm #define RK3308_GMAC_FLOW_CTRL GRF_BIT(3) 494b4ac9456STobias Schramm #define RK3308_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 495b4ac9456STobias Schramm #define RK3308_GMAC_SPEED_10M GRF_CLR_BIT(0) 496b4ac9456STobias Schramm #define RK3308_GMAC_SPEED_100M GRF_BIT(0) 497b4ac9456STobias Schramm 498b4ac9456STobias Schramm static void rk3308_set_to_rmii(struct rk_priv_data *bsp_priv) 499b4ac9456STobias Schramm { 500b4ac9456STobias Schramm struct device *dev = &bsp_priv->pdev->dev; 501b4ac9456STobias Schramm 502b4ac9456STobias Schramm if (IS_ERR(bsp_priv->grf)) { 503b4ac9456STobias Schramm dev_err(dev, "Missing rockchip,grf property\n"); 504b4ac9456STobias Schramm return; 505b4ac9456STobias Schramm } 506b4ac9456STobias Schramm 507b4ac9456STobias Schramm regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0, 508b4ac9456STobias Schramm RK3308_GMAC_PHY_INTF_SEL_RMII); 509b4ac9456STobias Schramm } 510b4ac9456STobias Schramm 511b4ac9456STobias Schramm static void rk3308_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 512b4ac9456STobias Schramm { 513b4ac9456STobias Schramm struct device *dev = &bsp_priv->pdev->dev; 514b4ac9456STobias Schramm 515b4ac9456STobias Schramm if (IS_ERR(bsp_priv->grf)) { 516b4ac9456STobias Schramm dev_err(dev, "Missing rockchip,grf property\n"); 517b4ac9456STobias Schramm return; 518b4ac9456STobias Schramm } 519b4ac9456STobias Schramm 520b4ac9456STobias Schramm if (speed == 10) { 521b4ac9456STobias Schramm regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0, 522b4ac9456STobias Schramm RK3308_GMAC_SPEED_10M); 523b4ac9456STobias Schramm } else if (speed == 100) { 524b4ac9456STobias Schramm regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0, 525b4ac9456STobias Schramm RK3308_GMAC_SPEED_100M); 526b4ac9456STobias Schramm } else { 527b4ac9456STobias Schramm dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 528b4ac9456STobias Schramm } 529b4ac9456STobias Schramm } 530b4ac9456STobias Schramm 531b4ac9456STobias Schramm static const struct rk_gmac_ops rk3308_ops = { 532b4ac9456STobias Schramm .set_to_rmii = rk3308_set_to_rmii, 533b4ac9456STobias Schramm .set_rmii_speed = rk3308_set_rmii_speed, 534b4ac9456STobias Schramm }; 535b4ac9456STobias Schramm 536d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON0 0x0900 537d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON1 0x0904 5388bdf63bdSDavid Wu #define RK3328_GRF_MAC_CON2 0x0908 5398bdf63bdSDavid Wu #define RK3328_GRF_MACPHY_CON1 0xb04 540d4ff816eSdavid.wu 541d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON0 */ 542d4ff816eSdavid.wu #define RK3328_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 543d4ff816eSdavid.wu #define RK3328_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 544d4ff816eSdavid.wu 545d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON1 */ 546d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RGMII \ 547d4ff816eSdavid.wu (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6)) 548d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RMII \ 549d4ff816eSdavid.wu (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6)) 550d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL GRF_BIT(3) 551d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 552d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_10M GRF_CLR_BIT(2) 553d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_100M GRF_BIT(2) 554d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_25M GRF_BIT(7) 555d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7) 556d4ff816eSdavid.wu #define RK3328_GMAC_CLK_125M (GRF_CLR_BIT(11) | GRF_CLR_BIT(12)) 557d4ff816eSdavid.wu #define RK3328_GMAC_CLK_25M (GRF_BIT(11) | GRF_BIT(12)) 558d4ff816eSdavid.wu #define RK3328_GMAC_CLK_2_5M (GRF_CLR_BIT(11) | GRF_BIT(12)) 559d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE GRF_BIT(9) 560d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE_CLR GRF_CLR_BIT(9) 561d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0) 562d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0) 563d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1) 564d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(0) 565d4ff816eSdavid.wu 5668bdf63bdSDavid Wu /* RK3328_GRF_MACPHY_CON1 */ 5678bdf63bdSDavid Wu #define RK3328_MACPHY_RMII_MODE GRF_BIT(9) 5688bdf63bdSDavid Wu 569d4ff816eSdavid.wu static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv, 570d4ff816eSdavid.wu int tx_delay, int rx_delay) 571d4ff816eSdavid.wu { 572d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev; 573d4ff816eSdavid.wu 574d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) { 575d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n"); 576d4ff816eSdavid.wu return; 577d4ff816eSdavid.wu } 578d4ff816eSdavid.wu 579d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, 580d4ff816eSdavid.wu RK3328_GMAC_PHY_INTF_SEL_RGMII | 581d4ff816eSdavid.wu RK3328_GMAC_RMII_MODE_CLR | 582d4ff816eSdavid.wu RK3328_GMAC_RXCLK_DLY_ENABLE | 583d4ff816eSdavid.wu RK3328_GMAC_TXCLK_DLY_ENABLE); 584d4ff816eSdavid.wu 585d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON0, 586d4ff816eSdavid.wu RK3328_GMAC_CLK_RX_DL_CFG(rx_delay) | 587d4ff816eSdavid.wu RK3328_GMAC_CLK_TX_DL_CFG(tx_delay)); 588d4ff816eSdavid.wu } 589d4ff816eSdavid.wu 590d4ff816eSdavid.wu static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv) 591d4ff816eSdavid.wu { 592d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev; 5938bdf63bdSDavid Wu unsigned int reg; 594d4ff816eSdavid.wu 595d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) { 596d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n"); 597d4ff816eSdavid.wu return; 598d4ff816eSdavid.wu } 599d4ff816eSdavid.wu 6008bdf63bdSDavid Wu reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 : 6018bdf63bdSDavid Wu RK3328_GRF_MAC_CON1; 6028bdf63bdSDavid Wu 6038bdf63bdSDavid Wu regmap_write(bsp_priv->grf, reg, 604d4ff816eSdavid.wu RK3328_GMAC_PHY_INTF_SEL_RMII | 605d4ff816eSdavid.wu RK3328_GMAC_RMII_MODE); 606d4ff816eSdavid.wu } 607d4ff816eSdavid.wu 608d4ff816eSdavid.wu static void rk3328_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 609d4ff816eSdavid.wu { 610d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev; 611d4ff816eSdavid.wu 612d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) { 613d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n"); 614d4ff816eSdavid.wu return; 615d4ff816eSdavid.wu } 616d4ff816eSdavid.wu 617d4ff816eSdavid.wu if (speed == 10) 618d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, 619d4ff816eSdavid.wu RK3328_GMAC_CLK_2_5M); 620d4ff816eSdavid.wu else if (speed == 100) 621d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, 622d4ff816eSdavid.wu RK3328_GMAC_CLK_25M); 623d4ff816eSdavid.wu else if (speed == 1000) 624d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, 625d4ff816eSdavid.wu RK3328_GMAC_CLK_125M); 626d4ff816eSdavid.wu else 627d4ff816eSdavid.wu dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 628d4ff816eSdavid.wu } 629d4ff816eSdavid.wu 630d4ff816eSdavid.wu static void rk3328_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 631d4ff816eSdavid.wu { 632d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev; 6338bdf63bdSDavid Wu unsigned int reg; 634d4ff816eSdavid.wu 635d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) { 636d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n"); 637d4ff816eSdavid.wu return; 638d4ff816eSdavid.wu } 639d4ff816eSdavid.wu 6408bdf63bdSDavid Wu reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 : 6418bdf63bdSDavid Wu RK3328_GRF_MAC_CON1; 6428bdf63bdSDavid Wu 643d4ff816eSdavid.wu if (speed == 10) 6448bdf63bdSDavid Wu regmap_write(bsp_priv->grf, reg, 645d4ff816eSdavid.wu RK3328_GMAC_RMII_CLK_2_5M | 646d4ff816eSdavid.wu RK3328_GMAC_SPEED_10M); 647d4ff816eSdavid.wu else if (speed == 100) 6488bdf63bdSDavid Wu regmap_write(bsp_priv->grf, reg, 649d4ff816eSdavid.wu RK3328_GMAC_RMII_CLK_25M | 650d4ff816eSdavid.wu RK3328_GMAC_SPEED_100M); 651d4ff816eSdavid.wu else 652d4ff816eSdavid.wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 653d4ff816eSdavid.wu } 654d4ff816eSdavid.wu 6558bdf63bdSDavid Wu static void rk3328_integrated_phy_powerup(struct rk_priv_data *priv) 6568bdf63bdSDavid Wu { 6578bdf63bdSDavid Wu regmap_write(priv->grf, RK3328_GRF_MACPHY_CON1, 6588bdf63bdSDavid Wu RK3328_MACPHY_RMII_MODE); 6598bdf63bdSDavid Wu } 6608bdf63bdSDavid Wu 661d4ff816eSdavid.wu static const struct rk_gmac_ops rk3328_ops = { 662d4ff816eSdavid.wu .set_to_rgmii = rk3328_set_to_rgmii, 663d4ff816eSdavid.wu .set_to_rmii = rk3328_set_to_rmii, 664d4ff816eSdavid.wu .set_rgmii_speed = rk3328_set_rgmii_speed, 665d4ff816eSdavid.wu .set_rmii_speed = rk3328_set_rmii_speed, 6668bdf63bdSDavid Wu .integrated_phy_powerup = rk3328_integrated_phy_powerup, 667d4ff816eSdavid.wu }; 668d4ff816eSdavid.wu 669ba289af8SRoger Chen #define RK3366_GRF_SOC_CON6 0x0418 670ba289af8SRoger Chen #define RK3366_GRF_SOC_CON7 0x041c 671ba289af8SRoger Chen 672ba289af8SRoger Chen /* RK3366_GRF_SOC_CON6 */ 673ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 674ba289af8SRoger Chen GRF_CLR_BIT(11)) 675ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 676ba289af8SRoger Chen GRF_BIT(11)) 677ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL GRF_BIT(8) 678ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 679ba289af8SRoger Chen #define RK3366_GMAC_SPEED_10M GRF_CLR_BIT(7) 680ba289af8SRoger Chen #define RK3366_GMAC_SPEED_100M GRF_BIT(7) 681ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_25M GRF_BIT(3) 682ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 683ba289af8SRoger Chen #define RK3366_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 684ba289af8SRoger Chen #define RK3366_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 685ba289af8SRoger Chen #define RK3366_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 686ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE GRF_BIT(6) 687ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 688ba289af8SRoger Chen 689ba289af8SRoger Chen /* RK3366_GRF_SOC_CON7 */ 690ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 691ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 692ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 693ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 694ba289af8SRoger Chen #define RK3366_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 695ba289af8SRoger Chen #define RK3366_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 696ba289af8SRoger Chen 697ba289af8SRoger Chen static void rk3366_set_to_rgmii(struct rk_priv_data *bsp_priv, 698ba289af8SRoger Chen int tx_delay, int rx_delay) 699ba289af8SRoger Chen { 700ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 701ba289af8SRoger Chen 702ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 703ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 704ba289af8SRoger Chen return; 705ba289af8SRoger Chen } 706ba289af8SRoger Chen 707ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 708ba289af8SRoger Chen RK3366_GMAC_PHY_INTF_SEL_RGMII | 709ba289af8SRoger Chen RK3366_GMAC_RMII_MODE_CLR); 710ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON7, 711eaf70ad1SWadim Egorov DELAY_ENABLE(RK3366, tx_delay, rx_delay) | 712ba289af8SRoger Chen RK3366_GMAC_CLK_RX_DL_CFG(rx_delay) | 713ba289af8SRoger Chen RK3366_GMAC_CLK_TX_DL_CFG(tx_delay)); 714ba289af8SRoger Chen } 715ba289af8SRoger Chen 716ba289af8SRoger Chen static void rk3366_set_to_rmii(struct rk_priv_data *bsp_priv) 717ba289af8SRoger Chen { 718ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 719ba289af8SRoger Chen 720ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 721ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 722ba289af8SRoger Chen return; 723ba289af8SRoger Chen } 724ba289af8SRoger Chen 725ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 726ba289af8SRoger Chen RK3366_GMAC_PHY_INTF_SEL_RMII | RK3366_GMAC_RMII_MODE); 727ba289af8SRoger Chen } 728ba289af8SRoger Chen 729ba289af8SRoger Chen static void rk3366_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 730ba289af8SRoger Chen { 731ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 732ba289af8SRoger Chen 733ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 734ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 735ba289af8SRoger Chen return; 736ba289af8SRoger Chen } 737ba289af8SRoger Chen 738ba289af8SRoger Chen if (speed == 10) 739ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 740ba289af8SRoger Chen RK3366_GMAC_CLK_2_5M); 741ba289af8SRoger Chen else if (speed == 100) 742ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 743ba289af8SRoger Chen RK3366_GMAC_CLK_25M); 744ba289af8SRoger Chen else if (speed == 1000) 745ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 746ba289af8SRoger Chen RK3366_GMAC_CLK_125M); 747ba289af8SRoger Chen else 748ba289af8SRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 749ba289af8SRoger Chen } 750ba289af8SRoger Chen 751ba289af8SRoger Chen static void rk3366_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 752ba289af8SRoger Chen { 753ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 754ba289af8SRoger Chen 755ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 756ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 757ba289af8SRoger Chen return; 758ba289af8SRoger Chen } 759ba289af8SRoger Chen 760ba289af8SRoger Chen if (speed == 10) { 761ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 762ba289af8SRoger Chen RK3366_GMAC_RMII_CLK_2_5M | 763ba289af8SRoger Chen RK3366_GMAC_SPEED_10M); 764ba289af8SRoger Chen } else if (speed == 100) { 765ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 766ba289af8SRoger Chen RK3366_GMAC_RMII_CLK_25M | 767ba289af8SRoger Chen RK3366_GMAC_SPEED_100M); 768ba289af8SRoger Chen } else { 769ba289af8SRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 770ba289af8SRoger Chen } 771ba289af8SRoger Chen } 772ba289af8SRoger Chen 773ba289af8SRoger Chen static const struct rk_gmac_ops rk3366_ops = { 774ba289af8SRoger Chen .set_to_rgmii = rk3366_set_to_rgmii, 775ba289af8SRoger Chen .set_to_rmii = rk3366_set_to_rmii, 776ba289af8SRoger Chen .set_rgmii_speed = rk3366_set_rgmii_speed, 777ba289af8SRoger Chen .set_rmii_speed = rk3366_set_rmii_speed, 778ba289af8SRoger Chen }; 779ba289af8SRoger Chen 780df558854SHeiko Stübner #define RK3368_GRF_SOC_CON15 0x043c 781df558854SHeiko Stübner #define RK3368_GRF_SOC_CON16 0x0440 782df558854SHeiko Stübner 783df558854SHeiko Stübner /* RK3368_GRF_SOC_CON15 */ 784df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 785df558854SHeiko Stübner GRF_CLR_BIT(11)) 786df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 787df558854SHeiko Stübner GRF_BIT(11)) 788df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL GRF_BIT(8) 789df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 790df558854SHeiko Stübner #define RK3368_GMAC_SPEED_10M GRF_CLR_BIT(7) 791df558854SHeiko Stübner #define RK3368_GMAC_SPEED_100M GRF_BIT(7) 792df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_25M GRF_BIT(3) 793df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 794df558854SHeiko Stübner #define RK3368_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 795df558854SHeiko Stübner #define RK3368_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 796df558854SHeiko Stübner #define RK3368_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 797df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE GRF_BIT(6) 798df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 799df558854SHeiko Stübner 800df558854SHeiko Stübner /* RK3368_GRF_SOC_CON16 */ 801df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 802df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 803df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 804df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 805df558854SHeiko Stübner #define RK3368_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 806df558854SHeiko Stübner #define RK3368_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 807df558854SHeiko Stübner 808df558854SHeiko Stübner static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv, 809df558854SHeiko Stübner int tx_delay, int rx_delay) 810df558854SHeiko Stübner { 811df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 812df558854SHeiko Stübner 813df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 814df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 815df558854SHeiko Stübner return; 816df558854SHeiko Stübner } 817df558854SHeiko Stübner 818df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 819df558854SHeiko Stübner RK3368_GMAC_PHY_INTF_SEL_RGMII | 820df558854SHeiko Stübner RK3368_GMAC_RMII_MODE_CLR); 821df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16, 822eaf70ad1SWadim Egorov DELAY_ENABLE(RK3368, tx_delay, rx_delay) | 823df558854SHeiko Stübner RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) | 824df558854SHeiko Stübner RK3368_GMAC_CLK_TX_DL_CFG(tx_delay)); 825df558854SHeiko Stübner } 826df558854SHeiko Stübner 827df558854SHeiko Stübner static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv) 828df558854SHeiko Stübner { 829df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 830df558854SHeiko Stübner 831df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 832df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 833df558854SHeiko Stübner return; 834df558854SHeiko Stübner } 835df558854SHeiko Stübner 836df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 837df558854SHeiko Stübner RK3368_GMAC_PHY_INTF_SEL_RMII | RK3368_GMAC_RMII_MODE); 838df558854SHeiko Stübner } 839df558854SHeiko Stübner 840df558854SHeiko Stübner static void rk3368_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 841df558854SHeiko Stübner { 842df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 843df558854SHeiko Stübner 844df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 845df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 846df558854SHeiko Stübner return; 847df558854SHeiko Stübner } 848df558854SHeiko Stübner 849df558854SHeiko Stübner if (speed == 10) 850df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 851df558854SHeiko Stübner RK3368_GMAC_CLK_2_5M); 852df558854SHeiko Stübner else if (speed == 100) 853df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 854df558854SHeiko Stübner RK3368_GMAC_CLK_25M); 855df558854SHeiko Stübner else if (speed == 1000) 856df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 857df558854SHeiko Stübner RK3368_GMAC_CLK_125M); 858df558854SHeiko Stübner else 859df558854SHeiko Stübner dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 860df558854SHeiko Stübner } 861df558854SHeiko Stübner 862df558854SHeiko Stübner static void rk3368_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 863df558854SHeiko Stübner { 864df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 865df558854SHeiko Stübner 866df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 867df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 868df558854SHeiko Stübner return; 869df558854SHeiko Stübner } 870df558854SHeiko Stübner 871df558854SHeiko Stübner if (speed == 10) { 872df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 873df558854SHeiko Stübner RK3368_GMAC_RMII_CLK_2_5M | 874df558854SHeiko Stübner RK3368_GMAC_SPEED_10M); 875df558854SHeiko Stübner } else if (speed == 100) { 876df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 877df558854SHeiko Stübner RK3368_GMAC_RMII_CLK_25M | 878df558854SHeiko Stübner RK3368_GMAC_SPEED_100M); 879df558854SHeiko Stübner } else { 880df558854SHeiko Stübner dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 881df558854SHeiko Stübner } 882df558854SHeiko Stübner } 883df558854SHeiko Stübner 88492c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3368_ops = { 885df558854SHeiko Stübner .set_to_rgmii = rk3368_set_to_rgmii, 886df558854SHeiko Stübner .set_to_rmii = rk3368_set_to_rmii, 887df558854SHeiko Stübner .set_rgmii_speed = rk3368_set_rgmii_speed, 888df558854SHeiko Stübner .set_rmii_speed = rk3368_set_rmii_speed, 889df558854SHeiko Stübner }; 890df558854SHeiko Stübner 891ba289af8SRoger Chen #define RK3399_GRF_SOC_CON5 0xc214 892ba289af8SRoger Chen #define RK3399_GRF_SOC_CON6 0xc218 893ba289af8SRoger Chen 894ba289af8SRoger Chen /* RK3399_GRF_SOC_CON5 */ 895ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 896ba289af8SRoger Chen GRF_CLR_BIT(11)) 897ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 898ba289af8SRoger Chen GRF_BIT(11)) 899ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL GRF_BIT(8) 900ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 901ba289af8SRoger Chen #define RK3399_GMAC_SPEED_10M GRF_CLR_BIT(7) 902ba289af8SRoger Chen #define RK3399_GMAC_SPEED_100M GRF_BIT(7) 903ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_25M GRF_BIT(3) 904ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 905ba289af8SRoger Chen #define RK3399_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 906ba289af8SRoger Chen #define RK3399_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 907ba289af8SRoger Chen #define RK3399_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 908ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE GRF_BIT(6) 909ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 910ba289af8SRoger Chen 911ba289af8SRoger Chen /* RK3399_GRF_SOC_CON6 */ 912ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 913ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 914ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 915ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 916ba289af8SRoger Chen #define RK3399_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 917ba289af8SRoger Chen #define RK3399_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 918ba289af8SRoger Chen 919ba289af8SRoger Chen static void rk3399_set_to_rgmii(struct rk_priv_data *bsp_priv, 920ba289af8SRoger Chen int tx_delay, int rx_delay) 921ba289af8SRoger Chen { 922ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 923ba289af8SRoger Chen 924ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 925ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 926ba289af8SRoger Chen return; 927ba289af8SRoger Chen } 928ba289af8SRoger Chen 929ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 930ba289af8SRoger Chen RK3399_GMAC_PHY_INTF_SEL_RGMII | 931ba289af8SRoger Chen RK3399_GMAC_RMII_MODE_CLR); 932ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON6, 933eaf70ad1SWadim Egorov DELAY_ENABLE(RK3399, tx_delay, rx_delay) | 934ba289af8SRoger Chen RK3399_GMAC_CLK_RX_DL_CFG(rx_delay) | 935ba289af8SRoger Chen RK3399_GMAC_CLK_TX_DL_CFG(tx_delay)); 936ba289af8SRoger Chen } 937ba289af8SRoger Chen 938ba289af8SRoger Chen static void rk3399_set_to_rmii(struct rk_priv_data *bsp_priv) 939ba289af8SRoger Chen { 940ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 941ba289af8SRoger Chen 942ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 943ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 944ba289af8SRoger Chen return; 945ba289af8SRoger Chen } 946ba289af8SRoger Chen 947ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 948ba289af8SRoger Chen RK3399_GMAC_PHY_INTF_SEL_RMII | RK3399_GMAC_RMII_MODE); 949ba289af8SRoger Chen } 950ba289af8SRoger Chen 951ba289af8SRoger Chen static void rk3399_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 952ba289af8SRoger Chen { 953ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 954ba289af8SRoger Chen 955ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 956ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 957ba289af8SRoger Chen return; 958ba289af8SRoger Chen } 959ba289af8SRoger Chen 960ba289af8SRoger Chen if (speed == 10) 961ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 962ba289af8SRoger Chen RK3399_GMAC_CLK_2_5M); 963ba289af8SRoger Chen else if (speed == 100) 964ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 965ba289af8SRoger Chen RK3399_GMAC_CLK_25M); 966ba289af8SRoger Chen else if (speed == 1000) 967ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 968ba289af8SRoger Chen RK3399_GMAC_CLK_125M); 969ba289af8SRoger Chen else 970ba289af8SRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 971ba289af8SRoger Chen } 972ba289af8SRoger Chen 973ba289af8SRoger Chen static void rk3399_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 974ba289af8SRoger Chen { 975ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 976ba289af8SRoger Chen 977ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 978ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 979ba289af8SRoger Chen return; 980ba289af8SRoger Chen } 981ba289af8SRoger Chen 982ba289af8SRoger Chen if (speed == 10) { 983ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 984ba289af8SRoger Chen RK3399_GMAC_RMII_CLK_2_5M | 985ba289af8SRoger Chen RK3399_GMAC_SPEED_10M); 986ba289af8SRoger Chen } else if (speed == 100) { 987ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 988ba289af8SRoger Chen RK3399_GMAC_RMII_CLK_25M | 989ba289af8SRoger Chen RK3399_GMAC_SPEED_100M); 990ba289af8SRoger Chen } else { 991ba289af8SRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 992ba289af8SRoger Chen } 993ba289af8SRoger Chen } 994ba289af8SRoger Chen 995ba289af8SRoger Chen static const struct rk_gmac_ops rk3399_ops = { 996ba289af8SRoger Chen .set_to_rgmii = rk3399_set_to_rgmii, 997ba289af8SRoger Chen .set_to_rmii = rk3399_set_to_rmii, 998ba289af8SRoger Chen .set_rgmii_speed = rk3399_set_rgmii_speed, 999ba289af8SRoger Chen .set_rmii_speed = rk3399_set_rmii_speed, 1000ba289af8SRoger Chen }; 1001ba289af8SRoger Chen 10023bb3d6b1SDavid Wu #define RK3568_GRF_GMAC0_CON0 0x0380 10033bb3d6b1SDavid Wu #define RK3568_GRF_GMAC0_CON1 0x0384 10043bb3d6b1SDavid Wu #define RK3568_GRF_GMAC1_CON0 0x0388 10053bb3d6b1SDavid Wu #define RK3568_GRF_GMAC1_CON1 0x038c 10063bb3d6b1SDavid Wu 10073bb3d6b1SDavid Wu /* RK3568_GRF_GMAC0_CON1 && RK3568_GRF_GMAC1_CON1 */ 10083bb3d6b1SDavid Wu #define RK3568_GMAC_PHY_INTF_SEL_RGMII \ 10093bb3d6b1SDavid Wu (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6)) 10103bb3d6b1SDavid Wu #define RK3568_GMAC_PHY_INTF_SEL_RMII \ 10113bb3d6b1SDavid Wu (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6)) 10123bb3d6b1SDavid Wu #define RK3568_GMAC_FLOW_CTRL GRF_BIT(3) 10133bb3d6b1SDavid Wu #define RK3568_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 10143bb3d6b1SDavid Wu #define RK3568_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1) 10153bb3d6b1SDavid Wu #define RK3568_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(1) 10163bb3d6b1SDavid Wu #define RK3568_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0) 10173bb3d6b1SDavid Wu #define RK3568_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0) 10183bb3d6b1SDavid Wu 10193bb3d6b1SDavid Wu /* RK3568_GRF_GMAC0_CON0 && RK3568_GRF_GMAC1_CON0 */ 10203bb3d6b1SDavid Wu #define RK3568_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 10213bb3d6b1SDavid Wu #define RK3568_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 10223bb3d6b1SDavid Wu 10233bb3d6b1SDavid Wu static void rk3568_set_to_rgmii(struct rk_priv_data *bsp_priv, 10243bb3d6b1SDavid Wu int tx_delay, int rx_delay) 10253bb3d6b1SDavid Wu { 10263bb3d6b1SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 10273bb3d6b1SDavid Wu u32 con0, con1; 10283bb3d6b1SDavid Wu 10293bb3d6b1SDavid Wu if (IS_ERR(bsp_priv->grf)) { 10303bb3d6b1SDavid Wu dev_err(dev, "Missing rockchip,grf property\n"); 10313bb3d6b1SDavid Wu return; 10323bb3d6b1SDavid Wu } 10333bb3d6b1SDavid Wu 10343bb3d6b1SDavid Wu con0 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON0 : 10353bb3d6b1SDavid Wu RK3568_GRF_GMAC0_CON0; 10363bb3d6b1SDavid Wu con1 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON1 : 10373bb3d6b1SDavid Wu RK3568_GRF_GMAC0_CON1; 10383bb3d6b1SDavid Wu 10393bb3d6b1SDavid Wu regmap_write(bsp_priv->grf, con0, 10403bb3d6b1SDavid Wu RK3568_GMAC_CLK_RX_DL_CFG(rx_delay) | 10413bb3d6b1SDavid Wu RK3568_GMAC_CLK_TX_DL_CFG(tx_delay)); 10423bb3d6b1SDavid Wu 10433bb3d6b1SDavid Wu regmap_write(bsp_priv->grf, con1, 10443bb3d6b1SDavid Wu RK3568_GMAC_PHY_INTF_SEL_RGMII | 10453bb3d6b1SDavid Wu RK3568_GMAC_RXCLK_DLY_ENABLE | 10463bb3d6b1SDavid Wu RK3568_GMAC_TXCLK_DLY_ENABLE); 10473bb3d6b1SDavid Wu } 10483bb3d6b1SDavid Wu 10493bb3d6b1SDavid Wu static void rk3568_set_to_rmii(struct rk_priv_data *bsp_priv) 10503bb3d6b1SDavid Wu { 10513bb3d6b1SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 10523bb3d6b1SDavid Wu u32 con1; 10533bb3d6b1SDavid Wu 10543bb3d6b1SDavid Wu if (IS_ERR(bsp_priv->grf)) { 10553bb3d6b1SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 10563bb3d6b1SDavid Wu return; 10573bb3d6b1SDavid Wu } 10583bb3d6b1SDavid Wu 10593bb3d6b1SDavid Wu con1 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON1 : 10603bb3d6b1SDavid Wu RK3568_GRF_GMAC0_CON1; 10613bb3d6b1SDavid Wu regmap_write(bsp_priv->grf, con1, RK3568_GMAC_PHY_INTF_SEL_RMII); 10623bb3d6b1SDavid Wu } 10633bb3d6b1SDavid Wu 10643bb3d6b1SDavid Wu static void rk3568_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed) 10653bb3d6b1SDavid Wu { 10663bb3d6b1SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 10673bb3d6b1SDavid Wu unsigned long rate; 10683bb3d6b1SDavid Wu int ret; 10693bb3d6b1SDavid Wu 10703bb3d6b1SDavid Wu switch (speed) { 10713bb3d6b1SDavid Wu case 10: 10723bb3d6b1SDavid Wu rate = 2500000; 10733bb3d6b1SDavid Wu break; 10743bb3d6b1SDavid Wu case 100: 10753bb3d6b1SDavid Wu rate = 25000000; 10763bb3d6b1SDavid Wu break; 10773bb3d6b1SDavid Wu case 1000: 10783bb3d6b1SDavid Wu rate = 125000000; 10793bb3d6b1SDavid Wu break; 10803bb3d6b1SDavid Wu default: 10813bb3d6b1SDavid Wu dev_err(dev, "unknown speed value for GMAC speed=%d", speed); 10823bb3d6b1SDavid Wu return; 10833bb3d6b1SDavid Wu } 10843bb3d6b1SDavid Wu 10853bb3d6b1SDavid Wu ret = clk_set_rate(bsp_priv->clk_mac_speed, rate); 10863bb3d6b1SDavid Wu if (ret) 10873bb3d6b1SDavid Wu dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n", 10883bb3d6b1SDavid Wu __func__, rate, ret); 10893bb3d6b1SDavid Wu } 10903bb3d6b1SDavid Wu 10913bb3d6b1SDavid Wu static const struct rk_gmac_ops rk3568_ops = { 10923bb3d6b1SDavid Wu .set_to_rgmii = rk3568_set_to_rgmii, 10933bb3d6b1SDavid Wu .set_to_rmii = rk3568_set_to_rmii, 10943bb3d6b1SDavid Wu .set_rgmii_speed = rk3568_set_gmac_speed, 10953bb3d6b1SDavid Wu .set_rmii_speed = rk3568_set_gmac_speed, 1096*0546b224SJohn Keeping .regs_valid = true, 10973bb3d6b1SDavid Wu .regs = { 10983bb3d6b1SDavid Wu 0xfe2a0000, /* gmac0 */ 10993bb3d6b1SDavid Wu 0xfe010000, /* gmac1 */ 11003bb3d6b1SDavid Wu 0x0, /* sentinel */ 11013bb3d6b1SDavid Wu }, 11023bb3d6b1SDavid Wu }; 11033bb3d6b1SDavid Wu 110489c9c163SDavid Wu #define RV1108_GRF_GMAC_CON0 0X0900 110589c9c163SDavid Wu 110689c9c163SDavid Wu /* RV1108_GRF_GMAC_CON0 */ 110789c9c163SDavid Wu #define RV1108_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \ 110889c9c163SDavid Wu GRF_BIT(6)) 110989c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL GRF_BIT(3) 111089c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 111189c9c163SDavid Wu #define RV1108_GMAC_SPEED_10M GRF_CLR_BIT(2) 111289c9c163SDavid Wu #define RV1108_GMAC_SPEED_100M GRF_BIT(2) 111389c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_25M GRF_BIT(7) 111489c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7) 111589c9c163SDavid Wu 111689c9c163SDavid Wu static void rv1108_set_to_rmii(struct rk_priv_data *bsp_priv) 111789c9c163SDavid Wu { 111889c9c163SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 111989c9c163SDavid Wu 112089c9c163SDavid Wu if (IS_ERR(bsp_priv->grf)) { 112189c9c163SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 112289c9c163SDavid Wu return; 112389c9c163SDavid Wu } 112489c9c163SDavid Wu 112589c9c163SDavid Wu regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0, 112689c9c163SDavid Wu RV1108_GMAC_PHY_INTF_SEL_RMII); 112789c9c163SDavid Wu } 112889c9c163SDavid Wu 112989c9c163SDavid Wu static void rv1108_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 113089c9c163SDavid Wu { 113189c9c163SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 113289c9c163SDavid Wu 113389c9c163SDavid Wu if (IS_ERR(bsp_priv->grf)) { 113489c9c163SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 113589c9c163SDavid Wu return; 113689c9c163SDavid Wu } 113789c9c163SDavid Wu 113889c9c163SDavid Wu if (speed == 10) { 113989c9c163SDavid Wu regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0, 114089c9c163SDavid Wu RV1108_GMAC_RMII_CLK_2_5M | 114189c9c163SDavid Wu RV1108_GMAC_SPEED_10M); 114289c9c163SDavid Wu } else if (speed == 100) { 114389c9c163SDavid Wu regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0, 114489c9c163SDavid Wu RV1108_GMAC_RMII_CLK_25M | 114589c9c163SDavid Wu RV1108_GMAC_SPEED_100M); 114689c9c163SDavid Wu } else { 114789c9c163SDavid Wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 114889c9c163SDavid Wu } 114989c9c163SDavid Wu } 115089c9c163SDavid Wu 115189c9c163SDavid Wu static const struct rk_gmac_ops rv1108_ops = { 115289c9c163SDavid Wu .set_to_rmii = rv1108_set_to_rmii, 115389c9c163SDavid Wu .set_rmii_speed = rv1108_set_rmii_speed, 115489c9c163SDavid Wu }; 115589c9c163SDavid Wu 1156fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON0 0xb00 1157fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON1 0xb04 1158fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON2 0xb08 1159fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON3 0xb0c 1160fecd4d7eSDavid Wu 1161fecd4d7eSDavid Wu #define RK_MACPHY_ENABLE GRF_BIT(0) 1162fecd4d7eSDavid Wu #define RK_MACPHY_DISABLE GRF_CLR_BIT(0) 1163fecd4d7eSDavid Wu #define RK_MACPHY_CFG_CLK_50M GRF_BIT(14) 1164fecd4d7eSDavid Wu #define RK_GMAC2PHY_RMII_MODE (GRF_BIT(6) | GRF_CLR_BIT(7)) 1165fecd4d7eSDavid Wu #define RK_GRF_CON2_MACPHY_ID HIWORD_UPDATE(0x1234, 0xffff, 0) 1166fecd4d7eSDavid Wu #define RK_GRF_CON3_MACPHY_ID HIWORD_UPDATE(0x35, 0x3f, 0) 1167fecd4d7eSDavid Wu 1168fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerup(struct rk_priv_data *priv) 11697ad269eaSRoger Chen { 1170fecd4d7eSDavid Wu if (priv->ops->integrated_phy_powerup) 1171fecd4d7eSDavid Wu priv->ops->integrated_phy_powerup(priv); 1172fecd4d7eSDavid Wu 1173fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M); 1174fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE); 1175fecd4d7eSDavid Wu 1176fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID); 1177fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID); 1178fecd4d7eSDavid Wu 1179fecd4d7eSDavid Wu if (priv->phy_reset) { 1180fecd4d7eSDavid Wu /* PHY needs to be disabled before trying to reset it */ 1181fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE); 1182fecd4d7eSDavid Wu if (priv->phy_reset) 1183fecd4d7eSDavid Wu reset_control_assert(priv->phy_reset); 1184fecd4d7eSDavid Wu usleep_range(10, 20); 1185fecd4d7eSDavid Wu if (priv->phy_reset) 1186fecd4d7eSDavid Wu reset_control_deassert(priv->phy_reset); 1187fecd4d7eSDavid Wu usleep_range(10, 20); 1188fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE); 1189fecd4d7eSDavid Wu msleep(30); 1190fecd4d7eSDavid Wu } 1191fecd4d7eSDavid Wu } 1192fecd4d7eSDavid Wu 1193fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerdown(struct rk_priv_data *priv) 1194fecd4d7eSDavid Wu { 1195fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE); 1196fecd4d7eSDavid Wu if (priv->phy_reset) 1197fecd4d7eSDavid Wu reset_control_assert(priv->phy_reset); 1198fecd4d7eSDavid Wu } 1199fecd4d7eSDavid Wu 1200fecd4d7eSDavid Wu static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat) 1201fecd4d7eSDavid Wu { 1202fecd4d7eSDavid Wu struct rk_priv_data *bsp_priv = plat->bsp_priv; 12037ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 1204fecd4d7eSDavid Wu int ret; 12057ad269eaSRoger Chen 12067ad269eaSRoger Chen bsp_priv->clk_enabled = false; 12077ad269eaSRoger Chen 12087ad269eaSRoger Chen bsp_priv->mac_clk_rx = devm_clk_get(dev, "mac_clk_rx"); 12097ad269eaSRoger Chen if (IS_ERR(bsp_priv->mac_clk_rx)) 1210d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1211d42202dcSRomain Perier "mac_clk_rx"); 12127ad269eaSRoger Chen 12137ad269eaSRoger Chen bsp_priv->mac_clk_tx = devm_clk_get(dev, "mac_clk_tx"); 12147ad269eaSRoger Chen if (IS_ERR(bsp_priv->mac_clk_tx)) 1215d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1216d42202dcSRomain Perier "mac_clk_tx"); 12177ad269eaSRoger Chen 12187ad269eaSRoger Chen bsp_priv->aclk_mac = devm_clk_get(dev, "aclk_mac"); 12197ad269eaSRoger Chen if (IS_ERR(bsp_priv->aclk_mac)) 1220d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1221d42202dcSRomain Perier "aclk_mac"); 12227ad269eaSRoger Chen 12237ad269eaSRoger Chen bsp_priv->pclk_mac = devm_clk_get(dev, "pclk_mac"); 12247ad269eaSRoger Chen if (IS_ERR(bsp_priv->pclk_mac)) 1225d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1226d42202dcSRomain Perier "pclk_mac"); 12277ad269eaSRoger Chen 12287ad269eaSRoger Chen bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth"); 12297ad269eaSRoger Chen if (IS_ERR(bsp_priv->clk_mac)) 1230d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1231d42202dcSRomain Perier "stmmaceth"); 12327ad269eaSRoger Chen 12337ad269eaSRoger Chen if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) { 12347ad269eaSRoger Chen bsp_priv->clk_mac_ref = devm_clk_get(dev, "clk_mac_ref"); 12357ad269eaSRoger Chen if (IS_ERR(bsp_priv->clk_mac_ref)) 1236d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1237d42202dcSRomain Perier "clk_mac_ref"); 12387ad269eaSRoger Chen 12397ad269eaSRoger Chen if (!bsp_priv->clock_input) { 12407ad269eaSRoger Chen bsp_priv->clk_mac_refout = 12417ad269eaSRoger Chen devm_clk_get(dev, "clk_mac_refout"); 12427ad269eaSRoger Chen if (IS_ERR(bsp_priv->clk_mac_refout)) 1243d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1244d42202dcSRomain Perier "clk_mac_refout"); 12457ad269eaSRoger Chen } 12467ad269eaSRoger Chen } 12477ad269eaSRoger Chen 124823c94d63SDavid Wu bsp_priv->clk_mac_speed = devm_clk_get(dev, "clk_mac_speed"); 124923c94d63SDavid Wu if (IS_ERR(bsp_priv->clk_mac_speed)) 125023c94d63SDavid Wu dev_err(dev, "cannot get clock %s\n", "clk_mac_speed"); 125123c94d63SDavid Wu 12527ad269eaSRoger Chen if (bsp_priv->clock_input) { 1253d42202dcSRomain Perier dev_info(dev, "clock input from PHY\n"); 12547ad269eaSRoger Chen } else { 12557ad269eaSRoger Chen if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) 1256c48fa33cSHeiko Stübner clk_set_rate(bsp_priv->clk_mac, 50000000); 12577ad269eaSRoger Chen } 12587ad269eaSRoger Chen 1259fecd4d7eSDavid Wu if (plat->phy_node && bsp_priv->integrated_phy) { 1260fecd4d7eSDavid Wu bsp_priv->clk_phy = of_clk_get(plat->phy_node, 0); 1261fecd4d7eSDavid Wu if (IS_ERR(bsp_priv->clk_phy)) { 1262fecd4d7eSDavid Wu ret = PTR_ERR(bsp_priv->clk_phy); 1263fecd4d7eSDavid Wu dev_err(dev, "Cannot get PHY clock: %d\n", ret); 1264fecd4d7eSDavid Wu return -EINVAL; 1265fecd4d7eSDavid Wu } 1266fecd4d7eSDavid Wu clk_set_rate(bsp_priv->clk_phy, 50000000); 1267fecd4d7eSDavid Wu } 1268fecd4d7eSDavid Wu 12697ad269eaSRoger Chen return 0; 12707ad269eaSRoger Chen } 12717ad269eaSRoger Chen 12727ad269eaSRoger Chen static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable) 12737ad269eaSRoger Chen { 1274428ad1bcSLABBE Corentin int phy_iface = bsp_priv->phy_iface; 12757ad269eaSRoger Chen 12767ad269eaSRoger Chen if (enable) { 12777ad269eaSRoger Chen if (!bsp_priv->clk_enabled) { 12787ad269eaSRoger Chen if (phy_iface == PHY_INTERFACE_MODE_RMII) { 12797ad269eaSRoger Chen if (!IS_ERR(bsp_priv->mac_clk_rx)) 12807ad269eaSRoger Chen clk_prepare_enable( 12817ad269eaSRoger Chen bsp_priv->mac_clk_rx); 12827ad269eaSRoger Chen 12837ad269eaSRoger Chen if (!IS_ERR(bsp_priv->clk_mac_ref)) 12847ad269eaSRoger Chen clk_prepare_enable( 12857ad269eaSRoger Chen bsp_priv->clk_mac_ref); 12867ad269eaSRoger Chen 12877ad269eaSRoger Chen if (!IS_ERR(bsp_priv->clk_mac_refout)) 12887ad269eaSRoger Chen clk_prepare_enable( 12897ad269eaSRoger Chen bsp_priv->clk_mac_refout); 12907ad269eaSRoger Chen } 12917ad269eaSRoger Chen 1292fecd4d7eSDavid Wu if (!IS_ERR(bsp_priv->clk_phy)) 1293fecd4d7eSDavid Wu clk_prepare_enable(bsp_priv->clk_phy); 1294fecd4d7eSDavid Wu 12957ad269eaSRoger Chen if (!IS_ERR(bsp_priv->aclk_mac)) 12967ad269eaSRoger Chen clk_prepare_enable(bsp_priv->aclk_mac); 12977ad269eaSRoger Chen 12987ad269eaSRoger Chen if (!IS_ERR(bsp_priv->pclk_mac)) 12997ad269eaSRoger Chen clk_prepare_enable(bsp_priv->pclk_mac); 13007ad269eaSRoger Chen 13017ad269eaSRoger Chen if (!IS_ERR(bsp_priv->mac_clk_tx)) 13027ad269eaSRoger Chen clk_prepare_enable(bsp_priv->mac_clk_tx); 13037ad269eaSRoger Chen 130423c94d63SDavid Wu if (!IS_ERR(bsp_priv->clk_mac_speed)) 130523c94d63SDavid Wu clk_prepare_enable(bsp_priv->clk_mac_speed); 130623c94d63SDavid Wu 13077ad269eaSRoger Chen /** 13087ad269eaSRoger Chen * if (!IS_ERR(bsp_priv->clk_mac)) 13097ad269eaSRoger Chen * clk_prepare_enable(bsp_priv->clk_mac); 13107ad269eaSRoger Chen */ 13117ad269eaSRoger Chen mdelay(5); 13127ad269eaSRoger Chen bsp_priv->clk_enabled = true; 13137ad269eaSRoger Chen } 13147ad269eaSRoger Chen } else { 13157ad269eaSRoger Chen if (bsp_priv->clk_enabled) { 13167ad269eaSRoger Chen if (phy_iface == PHY_INTERFACE_MODE_RMII) { 131793120ebaSYueHaibing clk_disable_unprepare(bsp_priv->mac_clk_rx); 13187ad269eaSRoger Chen 131993120ebaSYueHaibing clk_disable_unprepare(bsp_priv->clk_mac_ref); 13207ad269eaSRoger Chen 132193120ebaSYueHaibing clk_disable_unprepare(bsp_priv->clk_mac_refout); 13227ad269eaSRoger Chen } 13237ad269eaSRoger Chen 1324fecd4d7eSDavid Wu clk_disable_unprepare(bsp_priv->clk_phy); 1325fecd4d7eSDavid Wu 13267ad269eaSRoger Chen clk_disable_unprepare(bsp_priv->aclk_mac); 13277ad269eaSRoger Chen 13287ad269eaSRoger Chen clk_disable_unprepare(bsp_priv->pclk_mac); 13297ad269eaSRoger Chen 13307ad269eaSRoger Chen clk_disable_unprepare(bsp_priv->mac_clk_tx); 133123c94d63SDavid Wu 133223c94d63SDavid Wu clk_disable_unprepare(bsp_priv->clk_mac_speed); 13337ad269eaSRoger Chen /** 13347ad269eaSRoger Chen * if (!IS_ERR(bsp_priv->clk_mac)) 13357ad269eaSRoger Chen * clk_disable_unprepare(bsp_priv->clk_mac); 13367ad269eaSRoger Chen */ 13377ad269eaSRoger Chen bsp_priv->clk_enabled = false; 13387ad269eaSRoger Chen } 13397ad269eaSRoger Chen } 13407ad269eaSRoger Chen 13417ad269eaSRoger Chen return 0; 13427ad269eaSRoger Chen } 13437ad269eaSRoger Chen 13447ad269eaSRoger Chen static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable) 13457ad269eaSRoger Chen { 13462e12f536SRomain Perier struct regulator *ldo = bsp_priv->regulator; 13477ad269eaSRoger Chen int ret; 13487ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 13497ad269eaSRoger Chen 13503b25528eSChen-Yu Tsai if (!ldo) 13513b25528eSChen-Yu Tsai return 0; 13527ad269eaSRoger Chen 13537ad269eaSRoger Chen if (enable) { 13547ad269eaSRoger Chen ret = regulator_enable(ldo); 13552e12f536SRomain Perier if (ret) 1356d42202dcSRomain Perier dev_err(dev, "fail to enable phy-supply\n"); 13577ad269eaSRoger Chen } else { 13587ad269eaSRoger Chen ret = regulator_disable(ldo); 13592e12f536SRomain Perier if (ret) 1360d42202dcSRomain Perier dev_err(dev, "fail to disable phy-supply\n"); 13617ad269eaSRoger Chen } 13627ad269eaSRoger Chen 13637ad269eaSRoger Chen return 0; 13647ad269eaSRoger Chen } 13657ad269eaSRoger Chen 13660fb98db1SHeiko Stübner static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev, 1367fecd4d7eSDavid Wu struct plat_stmmacenet_data *plat, 136892c2588fSJoachim Eastwood const struct rk_gmac_ops *ops) 13697ad269eaSRoger Chen { 13707ad269eaSRoger Chen struct rk_priv_data *bsp_priv; 13717ad269eaSRoger Chen struct device *dev = &pdev->dev; 13723bb3d6b1SDavid Wu struct resource *res; 13737ad269eaSRoger Chen int ret; 13747ad269eaSRoger Chen const char *strings = NULL; 13757ad269eaSRoger Chen int value; 13767ad269eaSRoger Chen 13777ad269eaSRoger Chen bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL); 13787ad269eaSRoger Chen if (!bsp_priv) 13797ad269eaSRoger Chen return ERR_PTR(-ENOMEM); 13807ad269eaSRoger Chen 13810c65b2b9SAndrew Lunn of_get_phy_mode(dev->of_node, &bsp_priv->phy_iface); 13820fb98db1SHeiko Stübner bsp_priv->ops = ops; 13837ad269eaSRoger Chen 13843bb3d6b1SDavid Wu /* Some SoCs have multiple MAC controllers, which need 13853bb3d6b1SDavid Wu * to be distinguished. 13863bb3d6b1SDavid Wu */ 13873bb3d6b1SDavid Wu res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1388*0546b224SJohn Keeping if (res && ops->regs_valid) { 13893bb3d6b1SDavid Wu int i = 0; 13903bb3d6b1SDavid Wu 13913bb3d6b1SDavid Wu while (ops->regs[i]) { 13923bb3d6b1SDavid Wu if (ops->regs[i] == res->start) { 13933bb3d6b1SDavid Wu bsp_priv->id = i; 13943bb3d6b1SDavid Wu break; 13953bb3d6b1SDavid Wu } 13963bb3d6b1SDavid Wu i++; 13973bb3d6b1SDavid Wu } 13983bb3d6b1SDavid Wu } 13993bb3d6b1SDavid Wu 14002e12f536SRomain Perier bsp_priv->regulator = devm_regulator_get_optional(dev, "phy"); 14012e12f536SRomain Perier if (IS_ERR(bsp_priv->regulator)) { 14022e12f536SRomain Perier if (PTR_ERR(bsp_priv->regulator) == -EPROBE_DEFER) { 14032e12f536SRomain Perier dev_err(dev, "phy regulator is not available yet, deferred probing\n"); 14042e12f536SRomain Perier return ERR_PTR(-EPROBE_DEFER); 14052e12f536SRomain Perier } 14062e12f536SRomain Perier dev_err(dev, "no regulator found\n"); 14072e12f536SRomain Perier bsp_priv->regulator = NULL; 14087ad269eaSRoger Chen } 14097ad269eaSRoger Chen 14107ad269eaSRoger Chen ret = of_property_read_string(dev->of_node, "clock_in_out", &strings); 14117ad269eaSRoger Chen if (ret) { 1412d42202dcSRomain Perier dev_err(dev, "Can not read property: clock_in_out.\n"); 14137ad269eaSRoger Chen bsp_priv->clock_input = true; 14147ad269eaSRoger Chen } else { 1415d42202dcSRomain Perier dev_info(dev, "clock input or output? (%s).\n", 1416d42202dcSRomain Perier strings); 14177ad269eaSRoger Chen if (!strcmp(strings, "input")) 14187ad269eaSRoger Chen bsp_priv->clock_input = true; 14197ad269eaSRoger Chen else 14207ad269eaSRoger Chen bsp_priv->clock_input = false; 14217ad269eaSRoger Chen } 14227ad269eaSRoger Chen 14237ad269eaSRoger Chen ret = of_property_read_u32(dev->of_node, "tx_delay", &value); 14247ad269eaSRoger Chen if (ret) { 14257ad269eaSRoger Chen bsp_priv->tx_delay = 0x30; 1426d42202dcSRomain Perier dev_err(dev, "Can not read property: tx_delay."); 1427d42202dcSRomain Perier dev_err(dev, "set tx_delay to 0x%x\n", 1428d42202dcSRomain Perier bsp_priv->tx_delay); 14297ad269eaSRoger Chen } else { 1430d42202dcSRomain Perier dev_info(dev, "TX delay(0x%x).\n", value); 14317ad269eaSRoger Chen bsp_priv->tx_delay = value; 14327ad269eaSRoger Chen } 14337ad269eaSRoger Chen 14347ad269eaSRoger Chen ret = of_property_read_u32(dev->of_node, "rx_delay", &value); 14357ad269eaSRoger Chen if (ret) { 14367ad269eaSRoger Chen bsp_priv->rx_delay = 0x10; 1437d42202dcSRomain Perier dev_err(dev, "Can not read property: rx_delay."); 1438d42202dcSRomain Perier dev_err(dev, "set rx_delay to 0x%x\n", 1439d42202dcSRomain Perier bsp_priv->rx_delay); 14407ad269eaSRoger Chen } else { 1441d42202dcSRomain Perier dev_info(dev, "RX delay(0x%x).\n", value); 14427ad269eaSRoger Chen bsp_priv->rx_delay = value; 14437ad269eaSRoger Chen } 14447ad269eaSRoger Chen 14457ad269eaSRoger Chen bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node, 14467ad269eaSRoger Chen "rockchip,grf"); 14477ad269eaSRoger Chen 1448fecd4d7eSDavid Wu if (plat->phy_node) { 1449fecd4d7eSDavid Wu bsp_priv->integrated_phy = of_property_read_bool(plat->phy_node, 1450fecd4d7eSDavid Wu "phy-is-integrated"); 1451fecd4d7eSDavid Wu if (bsp_priv->integrated_phy) { 1452fecd4d7eSDavid Wu bsp_priv->phy_reset = of_reset_control_get(plat->phy_node, NULL); 1453fecd4d7eSDavid Wu if (IS_ERR(bsp_priv->phy_reset)) { 1454fecd4d7eSDavid Wu dev_err(&pdev->dev, "No PHY reset control found.\n"); 1455fecd4d7eSDavid Wu bsp_priv->phy_reset = NULL; 1456fecd4d7eSDavid Wu } 1457fecd4d7eSDavid Wu } 1458fecd4d7eSDavid Wu } 1459fecd4d7eSDavid Wu dev_info(dev, "integrated PHY? (%s).\n", 1460fecd4d7eSDavid Wu bsp_priv->integrated_phy ? "yes" : "no"); 1461fecd4d7eSDavid Wu 1462fecd4d7eSDavid Wu bsp_priv->pdev = pdev; 146345383f52SRoger Chen 146445383f52SRoger Chen return bsp_priv; 146545383f52SRoger Chen } 146645383f52SRoger Chen 146737c80d15SDavid Wu static int rk_gmac_check_ops(struct rk_priv_data *bsp_priv) 146837c80d15SDavid Wu { 146937c80d15SDavid Wu switch (bsp_priv->phy_iface) { 147037c80d15SDavid Wu case PHY_INTERFACE_MODE_RGMII: 147137c80d15SDavid Wu case PHY_INTERFACE_MODE_RGMII_ID: 147237c80d15SDavid Wu case PHY_INTERFACE_MODE_RGMII_RXID: 147337c80d15SDavid Wu case PHY_INTERFACE_MODE_RGMII_TXID: 147437c80d15SDavid Wu if (!bsp_priv->ops->set_to_rgmii) 147537c80d15SDavid Wu return -EINVAL; 147637c80d15SDavid Wu break; 147737c80d15SDavid Wu case PHY_INTERFACE_MODE_RMII: 147837c80d15SDavid Wu if (!bsp_priv->ops->set_to_rmii) 147937c80d15SDavid Wu return -EINVAL; 148037c80d15SDavid Wu break; 148137c80d15SDavid Wu default: 148237c80d15SDavid Wu dev_err(&bsp_priv->pdev->dev, 148337c80d15SDavid Wu "unsupported interface %d", bsp_priv->phy_iface); 148437c80d15SDavid Wu } 148537c80d15SDavid Wu return 0; 148637c80d15SDavid Wu } 148737c80d15SDavid Wu 148845383f52SRoger Chen static int rk_gmac_powerup(struct rk_priv_data *bsp_priv) 148945383f52SRoger Chen { 149045383f52SRoger Chen int ret; 149145383f52SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 149245383f52SRoger Chen 149337c80d15SDavid Wu ret = rk_gmac_check_ops(bsp_priv); 149437c80d15SDavid Wu if (ret) 149537c80d15SDavid Wu return ret; 149637c80d15SDavid Wu 1497f217bfdeSHeiko Stübner ret = gmac_clk_enable(bsp_priv, true); 1498f217bfdeSHeiko Stübner if (ret) 1499f217bfdeSHeiko Stübner return ret; 1500f217bfdeSHeiko Stübner 15017ad269eaSRoger Chen /*rmii or rgmii*/ 1502eaf70ad1SWadim Egorov switch (bsp_priv->phy_iface) { 1503eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII: 1504d42202dcSRomain Perier dev_info(dev, "init for RGMII\n"); 15050fb98db1SHeiko Stübner bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 15060fb98db1SHeiko Stübner bsp_priv->rx_delay); 1507eaf70ad1SWadim Egorov break; 1508eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_ID: 1509eaf70ad1SWadim Egorov dev_info(dev, "init for RGMII_ID\n"); 1510eaf70ad1SWadim Egorov bsp_priv->ops->set_to_rgmii(bsp_priv, 0, 0); 1511eaf70ad1SWadim Egorov break; 1512eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_RXID: 1513eaf70ad1SWadim Egorov dev_info(dev, "init for RGMII_RXID\n"); 1514eaf70ad1SWadim Egorov bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 0); 1515eaf70ad1SWadim Egorov break; 1516eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_TXID: 1517eaf70ad1SWadim Egorov dev_info(dev, "init for RGMII_TXID\n"); 1518eaf70ad1SWadim Egorov bsp_priv->ops->set_to_rgmii(bsp_priv, 0, bsp_priv->rx_delay); 1519eaf70ad1SWadim Egorov break; 1520eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RMII: 1521d42202dcSRomain Perier dev_info(dev, "init for RMII\n"); 15220fb98db1SHeiko Stübner bsp_priv->ops->set_to_rmii(bsp_priv); 1523eaf70ad1SWadim Egorov break; 1524eaf70ad1SWadim Egorov default: 1525d42202dcSRomain Perier dev_err(dev, "NO interface defined!\n"); 15267ad269eaSRoger Chen } 15277ad269eaSRoger Chen 15287ad269eaSRoger Chen ret = phy_power_on(bsp_priv, true); 1529c69c29a1SAlexey Khoroshilov if (ret) { 1530c69c29a1SAlexey Khoroshilov gmac_clk_enable(bsp_priv, false); 15317ad269eaSRoger Chen return ret; 1532c69c29a1SAlexey Khoroshilov } 15337ad269eaSRoger Chen 1534aec3f415SPunit Agrawal pm_runtime_get_sync(dev); 1535aec3f415SPunit Agrawal 1536fecd4d7eSDavid Wu if (bsp_priv->integrated_phy) 1537fecd4d7eSDavid Wu rk_gmac_integrated_phy_powerup(bsp_priv); 1538fecd4d7eSDavid Wu 15397ad269eaSRoger Chen return 0; 15407ad269eaSRoger Chen } 15417ad269eaSRoger Chen 1542229666c1SVincent Palatin static void rk_gmac_powerdown(struct rk_priv_data *gmac) 15437ad269eaSRoger Chen { 1544fecd4d7eSDavid Wu if (gmac->integrated_phy) 1545fecd4d7eSDavid Wu rk_gmac_integrated_phy_powerdown(gmac); 1546fecd4d7eSDavid Wu 1547aec3f415SPunit Agrawal pm_runtime_put_sync(&gmac->pdev->dev); 1548aec3f415SPunit Agrawal 15497ad269eaSRoger Chen phy_power_on(gmac, false); 15507ad269eaSRoger Chen gmac_clk_enable(gmac, false); 15517ad269eaSRoger Chen } 15527ad269eaSRoger Chen 15537ad269eaSRoger Chen static void rk_fix_speed(void *priv, unsigned int speed) 15547ad269eaSRoger Chen { 15557ad269eaSRoger Chen struct rk_priv_data *bsp_priv = priv; 15567ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 15577ad269eaSRoger Chen 1558eaf70ad1SWadim Egorov switch (bsp_priv->phy_iface) { 1559eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII: 1560eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_ID: 1561eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_RXID: 1562eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_TXID: 156337c80d15SDavid Wu if (bsp_priv->ops->set_rgmii_speed) 15640fb98db1SHeiko Stübner bsp_priv->ops->set_rgmii_speed(bsp_priv, speed); 1565eaf70ad1SWadim Egorov break; 1566eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RMII: 156737c80d15SDavid Wu if (bsp_priv->ops->set_rmii_speed) 15680fb98db1SHeiko Stübner bsp_priv->ops->set_rmii_speed(bsp_priv, speed); 1569eaf70ad1SWadim Egorov break; 1570eaf70ad1SWadim Egorov default: 15717ad269eaSRoger Chen dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface); 15727ad269eaSRoger Chen } 1573eaf70ad1SWadim Egorov } 15747ad269eaSRoger Chen 157527ffefd2SJoachim Eastwood static int rk_gmac_probe(struct platform_device *pdev) 157627ffefd2SJoachim Eastwood { 157727ffefd2SJoachim Eastwood struct plat_stmmacenet_data *plat_dat; 157827ffefd2SJoachim Eastwood struct stmmac_resources stmmac_res; 1579f529f182SJoachim Eastwood const struct rk_gmac_ops *data; 158027ffefd2SJoachim Eastwood int ret; 158127ffefd2SJoachim Eastwood 1582149adeddSJoachim Eastwood data = of_device_get_match_data(&pdev->dev); 1583149adeddSJoachim Eastwood if (!data) { 1584149adeddSJoachim Eastwood dev_err(&pdev->dev, "no of match data provided\n"); 1585149adeddSJoachim Eastwood return -EINVAL; 1586149adeddSJoachim Eastwood } 1587149adeddSJoachim Eastwood 158827ffefd2SJoachim Eastwood ret = stmmac_get_platform_resources(pdev, &stmmac_res); 158927ffefd2SJoachim Eastwood if (ret) 159027ffefd2SJoachim Eastwood return ret; 159127ffefd2SJoachim Eastwood 159283216e39SMichael Walle plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac); 159327ffefd2SJoachim Eastwood if (IS_ERR(plat_dat)) 159427ffefd2SJoachim Eastwood return PTR_ERR(plat_dat); 159527ffefd2SJoachim Eastwood 1596d6b06251SEzequiel Garcia /* If the stmmac is not already selected as gmac4, 1597d6b06251SEzequiel Garcia * then make sure we fallback to gmac. 1598d6b06251SEzequiel Garcia */ 1599d6b06251SEzequiel Garcia if (!plat_dat->has_gmac4) 160027ffefd2SJoachim Eastwood plat_dat->has_gmac = true; 160127ffefd2SJoachim Eastwood plat_dat->fix_mac_speed = rk_fix_speed; 160227ffefd2SJoachim Eastwood 1603fecd4d7eSDavid Wu plat_dat->bsp_priv = rk_gmac_setup(pdev, plat_dat, data); 1604d2ed0a77SJohan Hovold if (IS_ERR(plat_dat->bsp_priv)) { 1605d2ed0a77SJohan Hovold ret = PTR_ERR(plat_dat->bsp_priv); 1606d2ed0a77SJohan Hovold goto err_remove_config_dt; 1607d2ed0a77SJohan Hovold } 160827ffefd2SJoachim Eastwood 1609fecd4d7eSDavid Wu ret = rk_gmac_clk_init(plat_dat); 1610fecd4d7eSDavid Wu if (ret) 16119de9aa48SEmil Renner Berthing goto err_remove_config_dt; 1612fecd4d7eSDavid Wu 161307a5e769SJoachim Eastwood ret = rk_gmac_powerup(plat_dat->bsp_priv); 161427ffefd2SJoachim Eastwood if (ret) 1615d2ed0a77SJohan Hovold goto err_remove_config_dt; 161627ffefd2SJoachim Eastwood 16172d222656SJohan Hovold ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); 16182d222656SJohan Hovold if (ret) 16192745529aSDavid S. Miller goto err_gmac_powerdown; 16202d222656SJohan Hovold 16212d222656SJohan Hovold return 0; 16222d222656SJohan Hovold 16232745529aSDavid S. Miller err_gmac_powerdown: 16242745529aSDavid S. Miller rk_gmac_powerdown(plat_dat->bsp_priv); 1625d2ed0a77SJohan Hovold err_remove_config_dt: 1626d2ed0a77SJohan Hovold stmmac_remove_config_dt(pdev, plat_dat); 16272d222656SJohan Hovold 16282d222656SJohan Hovold return ret; 162927ffefd2SJoachim Eastwood } 163027ffefd2SJoachim Eastwood 16310de8c4c9SJoachim Eastwood static int rk_gmac_remove(struct platform_device *pdev) 16320de8c4c9SJoachim Eastwood { 16330de8c4c9SJoachim Eastwood struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(&pdev->dev); 16340de8c4c9SJoachim Eastwood int ret = stmmac_dvr_remove(&pdev->dev); 16350de8c4c9SJoachim Eastwood 16360de8c4c9SJoachim Eastwood rk_gmac_powerdown(bsp_priv); 16370de8c4c9SJoachim Eastwood 16380de8c4c9SJoachim Eastwood return ret; 16390de8c4c9SJoachim Eastwood } 16400de8c4c9SJoachim Eastwood 16415619468aSJoachim Eastwood #ifdef CONFIG_PM_SLEEP 16425619468aSJoachim Eastwood static int rk_gmac_suspend(struct device *dev) 16435619468aSJoachim Eastwood { 16445619468aSJoachim Eastwood struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev); 16455619468aSJoachim Eastwood int ret = stmmac_suspend(dev); 16465619468aSJoachim Eastwood 16475619468aSJoachim Eastwood /* Keep the PHY up if we use Wake-on-Lan. */ 16485619468aSJoachim Eastwood if (!device_may_wakeup(dev)) { 16495619468aSJoachim Eastwood rk_gmac_powerdown(bsp_priv); 16505619468aSJoachim Eastwood bsp_priv->suspended = true; 16515619468aSJoachim Eastwood } 16525619468aSJoachim Eastwood 16535619468aSJoachim Eastwood return ret; 16545619468aSJoachim Eastwood } 16555619468aSJoachim Eastwood 16565619468aSJoachim Eastwood static int rk_gmac_resume(struct device *dev) 16575619468aSJoachim Eastwood { 16585619468aSJoachim Eastwood struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev); 16595619468aSJoachim Eastwood 16605619468aSJoachim Eastwood /* The PHY was up for Wake-on-Lan. */ 16615619468aSJoachim Eastwood if (bsp_priv->suspended) { 16625619468aSJoachim Eastwood rk_gmac_powerup(bsp_priv); 16635619468aSJoachim Eastwood bsp_priv->suspended = false; 16645619468aSJoachim Eastwood } 16655619468aSJoachim Eastwood 16665619468aSJoachim Eastwood return stmmac_resume(dev); 16675619468aSJoachim Eastwood } 16685619468aSJoachim Eastwood #endif /* CONFIG_PM_SLEEP */ 16695619468aSJoachim Eastwood 16705619468aSJoachim Eastwood static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume); 16715619468aSJoachim Eastwood 1672e0fb4013SJoachim Eastwood static const struct of_device_id rk_gmac_dwmac_match[] = { 167323c94d63SDavid Wu { .compatible = "rockchip,px30-gmac", .data = &px30_ops }, 167405946876SDavid Wu { .compatible = "rockchip,rk3128-gmac", .data = &rk3128_ops }, 1675e7ffd812SXing Zheng { .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops }, 1676f529f182SJoachim Eastwood { .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops }, 1677b4ac9456STobias Schramm { .compatible = "rockchip,rk3308-gmac", .data = &rk3308_ops }, 1678d4ff816eSdavid.wu { .compatible = "rockchip,rk3328-gmac", .data = &rk3328_ops }, 1679ba289af8SRoger Chen { .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops }, 1680f529f182SJoachim Eastwood { .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops }, 1681ba289af8SRoger Chen { .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops }, 16823bb3d6b1SDavid Wu { .compatible = "rockchip,rk3568-gmac", .data = &rk3568_ops }, 168389c9c163SDavid Wu { .compatible = "rockchip,rv1108-gmac", .data = &rv1108_ops }, 1684e0fb4013SJoachim Eastwood { } 1685e0fb4013SJoachim Eastwood }; 1686e0fb4013SJoachim Eastwood MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match); 1687e0fb4013SJoachim Eastwood 1688e0fb4013SJoachim Eastwood static struct platform_driver rk_gmac_dwmac_driver = { 168927ffefd2SJoachim Eastwood .probe = rk_gmac_probe, 16900de8c4c9SJoachim Eastwood .remove = rk_gmac_remove, 1691e0fb4013SJoachim Eastwood .driver = { 1692e0fb4013SJoachim Eastwood .name = "rk_gmac-dwmac", 16935619468aSJoachim Eastwood .pm = &rk_gmac_pm_ops, 1694e0fb4013SJoachim Eastwood .of_match_table = rk_gmac_dwmac_match, 1695e0fb4013SJoachim Eastwood }, 1696e0fb4013SJoachim Eastwood }; 1697e0fb4013SJoachim Eastwood module_platform_driver(rk_gmac_dwmac_driver); 1698e0fb4013SJoachim Eastwood 1699e0fb4013SJoachim Eastwood MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>"); 1700e0fb4013SJoachim Eastwood MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer"); 1701e0fb4013SJoachim Eastwood MODULE_LICENSE("GPL"); 1702