17ad269eaSRoger Chen /** 27ad269eaSRoger Chen * dwmac-rk.c - Rockchip RK3288 DWMAC specific glue layer 37ad269eaSRoger Chen * 47ad269eaSRoger Chen * Copyright (C) 2014 Chen-Zhi (Roger Chen) 57ad269eaSRoger Chen * 67ad269eaSRoger Chen * Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com> 77ad269eaSRoger Chen * 87ad269eaSRoger Chen * This program is free software; you can redistribute it and/or modify 97ad269eaSRoger Chen * it under the terms of the GNU General Public License as published by 107ad269eaSRoger Chen * the Free Software Foundation; either version 2 of the License, or 117ad269eaSRoger Chen * (at your option) any later version. 127ad269eaSRoger Chen * 137ad269eaSRoger Chen * This program is distributed in the hope that it will be useful, 147ad269eaSRoger Chen * but WITHOUT ANY WARRANTY; without even the implied warranty of 157ad269eaSRoger Chen * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 167ad269eaSRoger Chen * GNU General Public License for more details. 177ad269eaSRoger Chen */ 187ad269eaSRoger Chen 197ad269eaSRoger Chen #include <linux/stmmac.h> 207ad269eaSRoger Chen #include <linux/bitops.h> 217ad269eaSRoger Chen #include <linux/clk.h> 227ad269eaSRoger Chen #include <linux/phy.h> 237ad269eaSRoger Chen #include <linux/of_net.h> 247ad269eaSRoger Chen #include <linux/gpio.h> 25e0fb4013SJoachim Eastwood #include <linux/module.h> 267ad269eaSRoger Chen #include <linux/of_gpio.h> 277ad269eaSRoger Chen #include <linux/of_device.h> 28e0fb4013SJoachim Eastwood #include <linux/platform_device.h> 297ad269eaSRoger Chen #include <linux/regulator/consumer.h> 307ad269eaSRoger Chen #include <linux/delay.h> 317ad269eaSRoger Chen #include <linux/mfd/syscon.h> 327ad269eaSRoger Chen #include <linux/regmap.h> 332c896fb0SDavid Wu #include <linux/pm_runtime.h> 347ad269eaSRoger Chen 35e0fb4013SJoachim Eastwood #include "stmmac_platform.h" 36e0fb4013SJoachim Eastwood 370fb98db1SHeiko Stübner struct rk_priv_data; 380fb98db1SHeiko Stübner struct rk_gmac_ops { 390fb98db1SHeiko Stübner void (*set_to_rgmii)(struct rk_priv_data *bsp_priv, 400fb98db1SHeiko Stübner int tx_delay, int rx_delay); 410fb98db1SHeiko Stübner void (*set_to_rmii)(struct rk_priv_data *bsp_priv); 420fb98db1SHeiko Stübner void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed); 430fb98db1SHeiko Stübner void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed); 44fecd4d7eSDavid Wu void (*integrated_phy_powerup)(struct rk_priv_data *bsp_priv); 450fb98db1SHeiko Stübner }; 460fb98db1SHeiko Stübner 477ad269eaSRoger Chen struct rk_priv_data { 487ad269eaSRoger Chen struct platform_device *pdev; 497ad269eaSRoger Chen int phy_iface; 502e12f536SRomain Perier struct regulator *regulator; 51229666c1SVincent Palatin bool suspended; 5292c2588fSJoachim Eastwood const struct rk_gmac_ops *ops; 537ad269eaSRoger Chen 547ad269eaSRoger Chen bool clk_enabled; 557ad269eaSRoger Chen bool clock_input; 56fecd4d7eSDavid Wu bool integrated_phy; 577ad269eaSRoger Chen 587ad269eaSRoger Chen struct clk *clk_mac; 597ad269eaSRoger Chen struct clk *gmac_clkin; 607ad269eaSRoger Chen struct clk *mac_clk_rx; 617ad269eaSRoger Chen struct clk *mac_clk_tx; 627ad269eaSRoger Chen struct clk *clk_mac_ref; 637ad269eaSRoger Chen struct clk *clk_mac_refout; 6423c94d63SDavid Wu struct clk *clk_mac_speed; 657ad269eaSRoger Chen struct clk *aclk_mac; 667ad269eaSRoger Chen struct clk *pclk_mac; 67fecd4d7eSDavid Wu struct clk *clk_phy; 68fecd4d7eSDavid Wu 69fecd4d7eSDavid Wu struct reset_control *phy_reset; 707ad269eaSRoger Chen 717ad269eaSRoger Chen int tx_delay; 727ad269eaSRoger Chen int rx_delay; 737ad269eaSRoger Chen 747ad269eaSRoger Chen struct regmap *grf; 757ad269eaSRoger Chen }; 767ad269eaSRoger Chen 777ad269eaSRoger Chen #define HIWORD_UPDATE(val, mask, shift) \ 787ad269eaSRoger Chen ((val) << (shift) | (mask) << ((shift) + 16)) 797ad269eaSRoger Chen 807ad269eaSRoger Chen #define GRF_BIT(nr) (BIT(nr) | BIT(nr+16)) 817ad269eaSRoger Chen #define GRF_CLR_BIT(nr) (BIT(nr+16)) 827ad269eaSRoger Chen 83eaf70ad1SWadim Egorov #define DELAY_ENABLE(soc, tx, rx) \ 84eaf70ad1SWadim Egorov (((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \ 85eaf70ad1SWadim Egorov ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE)) 86eaf70ad1SWadim Egorov 8723c94d63SDavid Wu #define PX30_GRF_GMAC_CON1 0x0904 8823c94d63SDavid Wu 8923c94d63SDavid Wu /* PX30_GRF_GMAC_CON1 */ 9023c94d63SDavid Wu #define PX30_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \ 9123c94d63SDavid Wu GRF_BIT(6)) 9223c94d63SDavid Wu #define PX30_GMAC_SPEED_10M GRF_CLR_BIT(2) 9323c94d63SDavid Wu #define PX30_GMAC_SPEED_100M GRF_BIT(2) 9423c94d63SDavid Wu 9523c94d63SDavid Wu static void px30_set_to_rmii(struct rk_priv_data *bsp_priv) 9623c94d63SDavid Wu { 9723c94d63SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 9823c94d63SDavid Wu 9923c94d63SDavid Wu if (IS_ERR(bsp_priv->grf)) { 10023c94d63SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 10123c94d63SDavid Wu return; 10223c94d63SDavid Wu } 10323c94d63SDavid Wu 10423c94d63SDavid Wu regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1, 10523c94d63SDavid Wu PX30_GMAC_PHY_INTF_SEL_RMII); 10623c94d63SDavid Wu } 10723c94d63SDavid Wu 10823c94d63SDavid Wu static void px30_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 10923c94d63SDavid Wu { 11023c94d63SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 11123c94d63SDavid Wu int ret; 11223c94d63SDavid Wu 11323c94d63SDavid Wu if (IS_ERR(bsp_priv->clk_mac_speed)) { 11423c94d63SDavid Wu dev_err(dev, "%s: Missing clk_mac_speed clock\n", __func__); 11523c94d63SDavid Wu return; 11623c94d63SDavid Wu } 11723c94d63SDavid Wu 11823c94d63SDavid Wu if (speed == 10) { 11923c94d63SDavid Wu regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1, 12023c94d63SDavid Wu PX30_GMAC_SPEED_10M); 12123c94d63SDavid Wu 12223c94d63SDavid Wu ret = clk_set_rate(bsp_priv->clk_mac_speed, 2500000); 12323c94d63SDavid Wu if (ret) 12423c94d63SDavid Wu dev_err(dev, "%s: set clk_mac_speed rate 2500000 failed: %d\n", 12523c94d63SDavid Wu __func__, ret); 12623c94d63SDavid Wu } else if (speed == 100) { 12723c94d63SDavid Wu regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1, 12823c94d63SDavid Wu PX30_GMAC_SPEED_100M); 12923c94d63SDavid Wu 13023c94d63SDavid Wu ret = clk_set_rate(bsp_priv->clk_mac_speed, 25000000); 13123c94d63SDavid Wu if (ret) 13223c94d63SDavid Wu dev_err(dev, "%s: set clk_mac_speed rate 25000000 failed: %d\n", 13323c94d63SDavid Wu __func__, ret); 13423c94d63SDavid Wu 13523c94d63SDavid Wu } else { 13623c94d63SDavid Wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 13723c94d63SDavid Wu } 13823c94d63SDavid Wu } 13923c94d63SDavid Wu 14023c94d63SDavid Wu static const struct rk_gmac_ops px30_ops = { 14123c94d63SDavid Wu .set_to_rmii = px30_set_to_rmii, 14223c94d63SDavid Wu .set_rmii_speed = px30_set_rmii_speed, 14323c94d63SDavid Wu }; 14423c94d63SDavid Wu 14505946876SDavid Wu #define RK3128_GRF_MAC_CON0 0x0168 14605946876SDavid Wu #define RK3128_GRF_MAC_CON1 0x016c 14705946876SDavid Wu 14805946876SDavid Wu /* RK3128_GRF_MAC_CON0 */ 14905946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_ENABLE GRF_BIT(14) 15005946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14) 15105946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 15205946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 15305946876SDavid Wu #define RK3128_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 15405946876SDavid Wu #define RK3128_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 15505946876SDavid Wu 15605946876SDavid Wu /* RK3128_GRF_MAC_CON1 */ 15705946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RGMII \ 15805946876SDavid Wu (GRF_BIT(6) | GRF_CLR_BIT(7) | GRF_CLR_BIT(8)) 15905946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RMII \ 16005946876SDavid Wu (GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | GRF_BIT(8)) 16105946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL GRF_BIT(9) 16205946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(9) 16305946876SDavid Wu #define RK3128_GMAC_SPEED_10M GRF_CLR_BIT(10) 16405946876SDavid Wu #define RK3128_GMAC_SPEED_100M GRF_BIT(10) 16505946876SDavid Wu #define RK3128_GMAC_RMII_CLK_25M GRF_BIT(11) 16605946876SDavid Wu #define RK3128_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(11) 16705946876SDavid Wu #define RK3128_GMAC_CLK_125M (GRF_CLR_BIT(12) | GRF_CLR_BIT(13)) 16805946876SDavid Wu #define RK3128_GMAC_CLK_25M (GRF_BIT(12) | GRF_BIT(13)) 16905946876SDavid Wu #define RK3128_GMAC_CLK_2_5M (GRF_CLR_BIT(12) | GRF_BIT(13)) 17005946876SDavid Wu #define RK3128_GMAC_RMII_MODE GRF_BIT(14) 17105946876SDavid Wu #define RK3128_GMAC_RMII_MODE_CLR GRF_CLR_BIT(14) 17205946876SDavid Wu 17305946876SDavid Wu static void rk3128_set_to_rgmii(struct rk_priv_data *bsp_priv, 17405946876SDavid Wu int tx_delay, int rx_delay) 17505946876SDavid Wu { 17605946876SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 17705946876SDavid Wu 17805946876SDavid Wu if (IS_ERR(bsp_priv->grf)) { 17905946876SDavid Wu dev_err(dev, "Missing rockchip,grf property\n"); 18005946876SDavid Wu return; 18105946876SDavid Wu } 18205946876SDavid Wu 18305946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 18405946876SDavid Wu RK3128_GMAC_PHY_INTF_SEL_RGMII | 18505946876SDavid Wu RK3128_GMAC_RMII_MODE_CLR); 18605946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON0, 18705946876SDavid Wu DELAY_ENABLE(RK3128, tx_delay, rx_delay) | 18805946876SDavid Wu RK3128_GMAC_CLK_RX_DL_CFG(rx_delay) | 18905946876SDavid Wu RK3128_GMAC_CLK_TX_DL_CFG(tx_delay)); 19005946876SDavid Wu } 19105946876SDavid Wu 19205946876SDavid Wu static void rk3128_set_to_rmii(struct rk_priv_data *bsp_priv) 19305946876SDavid Wu { 19405946876SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 19505946876SDavid Wu 19605946876SDavid Wu if (IS_ERR(bsp_priv->grf)) { 19705946876SDavid Wu dev_err(dev, "Missing rockchip,grf property\n"); 19805946876SDavid Wu return; 19905946876SDavid Wu } 20005946876SDavid Wu 20105946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 20205946876SDavid Wu RK3128_GMAC_PHY_INTF_SEL_RMII | RK3128_GMAC_RMII_MODE); 20305946876SDavid Wu } 20405946876SDavid Wu 20505946876SDavid Wu static void rk3128_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 20605946876SDavid Wu { 20705946876SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 20805946876SDavid Wu 20905946876SDavid Wu if (IS_ERR(bsp_priv->grf)) { 21005946876SDavid Wu dev_err(dev, "Missing rockchip,grf property\n"); 21105946876SDavid Wu return; 21205946876SDavid Wu } 21305946876SDavid Wu 21405946876SDavid Wu if (speed == 10) 21505946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 21605946876SDavid Wu RK3128_GMAC_CLK_2_5M); 21705946876SDavid Wu else if (speed == 100) 21805946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 21905946876SDavid Wu RK3128_GMAC_CLK_25M); 22005946876SDavid Wu else if (speed == 1000) 22105946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 22205946876SDavid Wu RK3128_GMAC_CLK_125M); 22305946876SDavid Wu else 22405946876SDavid Wu dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 22505946876SDavid Wu } 22605946876SDavid Wu 22705946876SDavid Wu static void rk3128_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 22805946876SDavid Wu { 22905946876SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 23005946876SDavid Wu 23105946876SDavid Wu if (IS_ERR(bsp_priv->grf)) { 23205946876SDavid Wu dev_err(dev, "Missing rockchip,grf property\n"); 23305946876SDavid Wu return; 23405946876SDavid Wu } 23505946876SDavid Wu 23605946876SDavid Wu if (speed == 10) { 23705946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 23805946876SDavid Wu RK3128_GMAC_RMII_CLK_2_5M | 23905946876SDavid Wu RK3128_GMAC_SPEED_10M); 24005946876SDavid Wu } else if (speed == 100) { 24105946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 24205946876SDavid Wu RK3128_GMAC_RMII_CLK_25M | 24305946876SDavid Wu RK3128_GMAC_SPEED_100M); 24405946876SDavid Wu } else { 24505946876SDavid Wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 24605946876SDavid Wu } 24705946876SDavid Wu } 24805946876SDavid Wu 24905946876SDavid Wu static const struct rk_gmac_ops rk3128_ops = { 25005946876SDavid Wu .set_to_rgmii = rk3128_set_to_rgmii, 25105946876SDavid Wu .set_to_rmii = rk3128_set_to_rmii, 25205946876SDavid Wu .set_rgmii_speed = rk3128_set_rgmii_speed, 25305946876SDavid Wu .set_rmii_speed = rk3128_set_rmii_speed, 25405946876SDavid Wu }; 25505946876SDavid Wu 256e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON0 0x0900 257e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON1 0x0904 258e7ffd812SXing Zheng 2596fa12c78SDavid Wu #define RK3228_GRF_CON_MUX 0x50 2606fa12c78SDavid Wu 261e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON0 */ 262e7ffd812SXing Zheng #define RK3228_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 263e7ffd812SXing Zheng #define RK3228_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 264e7ffd812SXing Zheng 265e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON1 */ 266e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RGMII \ 267e7ffd812SXing Zheng (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6)) 268e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RMII \ 269e7ffd812SXing Zheng (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6)) 270e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL GRF_BIT(3) 271e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 272e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_10M GRF_CLR_BIT(2) 273e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_100M GRF_BIT(2) 274e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_25M GRF_BIT(7) 275e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7) 276e7ffd812SXing Zheng #define RK3228_GMAC_CLK_125M (GRF_CLR_BIT(8) | GRF_CLR_BIT(9)) 277e7ffd812SXing Zheng #define RK3228_GMAC_CLK_25M (GRF_BIT(8) | GRF_BIT(9)) 278e7ffd812SXing Zheng #define RK3228_GMAC_CLK_2_5M (GRF_CLR_BIT(8) | GRF_BIT(9)) 279e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE GRF_BIT(10) 280e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE_CLR GRF_CLR_BIT(10) 281e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0) 282e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0) 283e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1) 284e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(1) 285e7ffd812SXing Zheng 2866fa12c78SDavid Wu /* RK3228_GRF_COM_MUX */ 2876fa12c78SDavid Wu #define RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY GRF_BIT(15) 2886fa12c78SDavid Wu 289e7ffd812SXing Zheng static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv, 290e7ffd812SXing Zheng int tx_delay, int rx_delay) 291e7ffd812SXing Zheng { 292e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 293e7ffd812SXing Zheng 294e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 295e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 296e7ffd812SXing Zheng return; 297e7ffd812SXing Zheng } 298e7ffd812SXing Zheng 299e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 300e7ffd812SXing Zheng RK3228_GMAC_PHY_INTF_SEL_RGMII | 301e7ffd812SXing Zheng RK3228_GMAC_RMII_MODE_CLR | 302eaf70ad1SWadim Egorov DELAY_ENABLE(RK3228, tx_delay, rx_delay)); 303e7ffd812SXing Zheng 304e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON0, 305e7ffd812SXing Zheng RK3228_GMAC_CLK_RX_DL_CFG(rx_delay) | 306e7ffd812SXing Zheng RK3228_GMAC_CLK_TX_DL_CFG(tx_delay)); 307e7ffd812SXing Zheng } 308e7ffd812SXing Zheng 309e7ffd812SXing Zheng static void rk3228_set_to_rmii(struct rk_priv_data *bsp_priv) 310e7ffd812SXing Zheng { 311e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 312e7ffd812SXing Zheng 313e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 314e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 315e7ffd812SXing Zheng return; 316e7ffd812SXing Zheng } 317e7ffd812SXing Zheng 318e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 319e7ffd812SXing Zheng RK3228_GMAC_PHY_INTF_SEL_RMII | 320e7ffd812SXing Zheng RK3228_GMAC_RMII_MODE); 321e7ffd812SXing Zheng 322e7ffd812SXing Zheng /* set MAC to RMII mode */ 323e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, GRF_BIT(11)); 324e7ffd812SXing Zheng } 325e7ffd812SXing Zheng 326e7ffd812SXing Zheng static void rk3228_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 327e7ffd812SXing Zheng { 328e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 329e7ffd812SXing Zheng 330e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 331e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 332e7ffd812SXing Zheng return; 333e7ffd812SXing Zheng } 334e7ffd812SXing Zheng 335e7ffd812SXing Zheng if (speed == 10) 336e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 337e7ffd812SXing Zheng RK3228_GMAC_CLK_2_5M); 338e7ffd812SXing Zheng else if (speed == 100) 339e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 340e7ffd812SXing Zheng RK3228_GMAC_CLK_25M); 341e7ffd812SXing Zheng else if (speed == 1000) 342e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 343e7ffd812SXing Zheng RK3228_GMAC_CLK_125M); 344e7ffd812SXing Zheng else 345e7ffd812SXing Zheng dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 346e7ffd812SXing Zheng } 347e7ffd812SXing Zheng 348e7ffd812SXing Zheng static void rk3228_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 349e7ffd812SXing Zheng { 350e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 351e7ffd812SXing Zheng 352e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 353e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 354e7ffd812SXing Zheng return; 355e7ffd812SXing Zheng } 356e7ffd812SXing Zheng 357e7ffd812SXing Zheng if (speed == 10) 358e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 359e7ffd812SXing Zheng RK3228_GMAC_RMII_CLK_2_5M | 360e7ffd812SXing Zheng RK3228_GMAC_SPEED_10M); 361e7ffd812SXing Zheng else if (speed == 100) 362e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 363e7ffd812SXing Zheng RK3228_GMAC_RMII_CLK_25M | 364e7ffd812SXing Zheng RK3228_GMAC_SPEED_100M); 365e7ffd812SXing Zheng else 366e7ffd812SXing Zheng dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 367e7ffd812SXing Zheng } 368e7ffd812SXing Zheng 3696fa12c78SDavid Wu static void rk3228_integrated_phy_powerup(struct rk_priv_data *priv) 3706fa12c78SDavid Wu { 3716fa12c78SDavid Wu regmap_write(priv->grf, RK3228_GRF_CON_MUX, 3726fa12c78SDavid Wu RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY); 3736fa12c78SDavid Wu } 3746fa12c78SDavid Wu 375e7ffd812SXing Zheng static const struct rk_gmac_ops rk3228_ops = { 376e7ffd812SXing Zheng .set_to_rgmii = rk3228_set_to_rgmii, 377e7ffd812SXing Zheng .set_to_rmii = rk3228_set_to_rmii, 378e7ffd812SXing Zheng .set_rgmii_speed = rk3228_set_rgmii_speed, 379e7ffd812SXing Zheng .set_rmii_speed = rk3228_set_rmii_speed, 3806fa12c78SDavid Wu .integrated_phy_powerup = rk3228_integrated_phy_powerup, 381e7ffd812SXing Zheng }; 382e7ffd812SXing Zheng 3837ad269eaSRoger Chen #define RK3288_GRF_SOC_CON1 0x0248 3847ad269eaSRoger Chen #define RK3288_GRF_SOC_CON3 0x0250 3857ad269eaSRoger Chen 3867ad269eaSRoger Chen /*RK3288_GRF_SOC_CON1*/ 3870fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(6) | GRF_CLR_BIT(7) | \ 3880fb98db1SHeiko Stübner GRF_CLR_BIT(8)) 3890fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | \ 3900fb98db1SHeiko Stübner GRF_BIT(8)) 3910fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL GRF_BIT(9) 3920fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(9) 3930fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_10M GRF_CLR_BIT(10) 3940fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_100M GRF_BIT(10) 3950fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_25M GRF_BIT(11) 3960fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(11) 3970fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_125M (GRF_CLR_BIT(12) | GRF_CLR_BIT(13)) 3980fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_25M (GRF_BIT(12) | GRF_BIT(13)) 3990fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_2_5M (GRF_CLR_BIT(12) | GRF_BIT(13)) 4000fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE GRF_BIT(14) 4010fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE_CLR GRF_CLR_BIT(14) 4027ad269eaSRoger Chen 4037ad269eaSRoger Chen /*RK3288_GRF_SOC_CON3*/ 4040fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_ENABLE GRF_BIT(14) 4050fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14) 4060fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 4070fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 4080fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 4090fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 4107ad269eaSRoger Chen 4110fb98db1SHeiko Stübner static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv, 4127ad269eaSRoger Chen int tx_delay, int rx_delay) 4137ad269eaSRoger Chen { 4147ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 4157ad269eaSRoger Chen 4167ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 417d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 4187ad269eaSRoger Chen return; 4197ad269eaSRoger Chen } 4207ad269eaSRoger Chen 4217ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4220fb98db1SHeiko Stübner RK3288_GMAC_PHY_INTF_SEL_RGMII | 4230fb98db1SHeiko Stübner RK3288_GMAC_RMII_MODE_CLR); 4247ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3, 425eaf70ad1SWadim Egorov DELAY_ENABLE(RK3288, tx_delay, rx_delay) | 4260fb98db1SHeiko Stübner RK3288_GMAC_CLK_RX_DL_CFG(rx_delay) | 4270fb98db1SHeiko Stübner RK3288_GMAC_CLK_TX_DL_CFG(tx_delay)); 4287ad269eaSRoger Chen } 4297ad269eaSRoger Chen 4300fb98db1SHeiko Stübner static void rk3288_set_to_rmii(struct rk_priv_data *bsp_priv) 4317ad269eaSRoger Chen { 4327ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 4337ad269eaSRoger Chen 4347ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 435d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 4367ad269eaSRoger Chen return; 4377ad269eaSRoger Chen } 4387ad269eaSRoger Chen 4397ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4400fb98db1SHeiko Stübner RK3288_GMAC_PHY_INTF_SEL_RMII | RK3288_GMAC_RMII_MODE); 4417ad269eaSRoger Chen } 4427ad269eaSRoger Chen 4430fb98db1SHeiko Stübner static void rk3288_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 4447ad269eaSRoger Chen { 4457ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 4467ad269eaSRoger Chen 4477ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 448d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 4497ad269eaSRoger Chen return; 4507ad269eaSRoger Chen } 4517ad269eaSRoger Chen 4527ad269eaSRoger Chen if (speed == 10) 4530fb98db1SHeiko Stübner regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4540fb98db1SHeiko Stübner RK3288_GMAC_CLK_2_5M); 4557ad269eaSRoger Chen else if (speed == 100) 4560fb98db1SHeiko Stübner regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4570fb98db1SHeiko Stübner RK3288_GMAC_CLK_25M); 4587ad269eaSRoger Chen else if (speed == 1000) 4590fb98db1SHeiko Stübner regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4600fb98db1SHeiko Stübner RK3288_GMAC_CLK_125M); 4617ad269eaSRoger Chen else 4627ad269eaSRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 4637ad269eaSRoger Chen } 4647ad269eaSRoger Chen 4650fb98db1SHeiko Stübner static void rk3288_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 4667ad269eaSRoger Chen { 4677ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 4687ad269eaSRoger Chen 4697ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 470d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 4717ad269eaSRoger Chen return; 4727ad269eaSRoger Chen } 4737ad269eaSRoger Chen 4747ad269eaSRoger Chen if (speed == 10) { 4757ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4760fb98db1SHeiko Stübner RK3288_GMAC_RMII_CLK_2_5M | 4770fb98db1SHeiko Stübner RK3288_GMAC_SPEED_10M); 4787ad269eaSRoger Chen } else if (speed == 100) { 4797ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4800fb98db1SHeiko Stübner RK3288_GMAC_RMII_CLK_25M | 4810fb98db1SHeiko Stübner RK3288_GMAC_SPEED_100M); 4827ad269eaSRoger Chen } else { 4837ad269eaSRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 4847ad269eaSRoger Chen } 4857ad269eaSRoger Chen } 4867ad269eaSRoger Chen 48792c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3288_ops = { 4880fb98db1SHeiko Stübner .set_to_rgmii = rk3288_set_to_rgmii, 4890fb98db1SHeiko Stübner .set_to_rmii = rk3288_set_to_rmii, 4900fb98db1SHeiko Stübner .set_rgmii_speed = rk3288_set_rgmii_speed, 4910fb98db1SHeiko Stübner .set_rmii_speed = rk3288_set_rmii_speed, 4920fb98db1SHeiko Stübner }; 4930fb98db1SHeiko Stübner 494d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON0 0x0900 495d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON1 0x0904 4968bdf63bdSDavid Wu #define RK3328_GRF_MAC_CON2 0x0908 4978bdf63bdSDavid Wu #define RK3328_GRF_MACPHY_CON1 0xb04 498d4ff816eSdavid.wu 499d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON0 */ 500d4ff816eSdavid.wu #define RK3328_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 501d4ff816eSdavid.wu #define RK3328_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 502d4ff816eSdavid.wu 503d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON1 */ 504d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RGMII \ 505d4ff816eSdavid.wu (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6)) 506d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RMII \ 507d4ff816eSdavid.wu (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6)) 508d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL GRF_BIT(3) 509d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 510d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_10M GRF_CLR_BIT(2) 511d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_100M GRF_BIT(2) 512d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_25M GRF_BIT(7) 513d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7) 514d4ff816eSdavid.wu #define RK3328_GMAC_CLK_125M (GRF_CLR_BIT(11) | GRF_CLR_BIT(12)) 515d4ff816eSdavid.wu #define RK3328_GMAC_CLK_25M (GRF_BIT(11) | GRF_BIT(12)) 516d4ff816eSdavid.wu #define RK3328_GMAC_CLK_2_5M (GRF_CLR_BIT(11) | GRF_BIT(12)) 517d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE GRF_BIT(9) 518d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE_CLR GRF_CLR_BIT(9) 519d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0) 520d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0) 521d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1) 522d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(0) 523d4ff816eSdavid.wu 5248bdf63bdSDavid Wu /* RK3328_GRF_MACPHY_CON1 */ 5258bdf63bdSDavid Wu #define RK3328_MACPHY_RMII_MODE GRF_BIT(9) 5268bdf63bdSDavid Wu 527d4ff816eSdavid.wu static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv, 528d4ff816eSdavid.wu int tx_delay, int rx_delay) 529d4ff816eSdavid.wu { 530d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev; 531d4ff816eSdavid.wu 532d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) { 533d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n"); 534d4ff816eSdavid.wu return; 535d4ff816eSdavid.wu } 536d4ff816eSdavid.wu 537d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, 538d4ff816eSdavid.wu RK3328_GMAC_PHY_INTF_SEL_RGMII | 539d4ff816eSdavid.wu RK3328_GMAC_RMII_MODE_CLR | 540d4ff816eSdavid.wu RK3328_GMAC_RXCLK_DLY_ENABLE | 541d4ff816eSdavid.wu RK3328_GMAC_TXCLK_DLY_ENABLE); 542d4ff816eSdavid.wu 543d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON0, 544d4ff816eSdavid.wu RK3328_GMAC_CLK_RX_DL_CFG(rx_delay) | 545d4ff816eSdavid.wu RK3328_GMAC_CLK_TX_DL_CFG(tx_delay)); 546d4ff816eSdavid.wu } 547d4ff816eSdavid.wu 548d4ff816eSdavid.wu static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv) 549d4ff816eSdavid.wu { 550d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev; 5518bdf63bdSDavid Wu unsigned int reg; 552d4ff816eSdavid.wu 553d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) { 554d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n"); 555d4ff816eSdavid.wu return; 556d4ff816eSdavid.wu } 557d4ff816eSdavid.wu 5588bdf63bdSDavid Wu reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 : 5598bdf63bdSDavid Wu RK3328_GRF_MAC_CON1; 5608bdf63bdSDavid Wu 5618bdf63bdSDavid Wu regmap_write(bsp_priv->grf, reg, 562d4ff816eSdavid.wu RK3328_GMAC_PHY_INTF_SEL_RMII | 563d4ff816eSdavid.wu RK3328_GMAC_RMII_MODE); 564d4ff816eSdavid.wu } 565d4ff816eSdavid.wu 566d4ff816eSdavid.wu static void rk3328_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 567d4ff816eSdavid.wu { 568d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev; 569d4ff816eSdavid.wu 570d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) { 571d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n"); 572d4ff816eSdavid.wu return; 573d4ff816eSdavid.wu } 574d4ff816eSdavid.wu 575d4ff816eSdavid.wu if (speed == 10) 576d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, 577d4ff816eSdavid.wu RK3328_GMAC_CLK_2_5M); 578d4ff816eSdavid.wu else if (speed == 100) 579d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, 580d4ff816eSdavid.wu RK3328_GMAC_CLK_25M); 581d4ff816eSdavid.wu else if (speed == 1000) 582d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, 583d4ff816eSdavid.wu RK3328_GMAC_CLK_125M); 584d4ff816eSdavid.wu else 585d4ff816eSdavid.wu dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 586d4ff816eSdavid.wu } 587d4ff816eSdavid.wu 588d4ff816eSdavid.wu static void rk3328_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 589d4ff816eSdavid.wu { 590d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev; 5918bdf63bdSDavid Wu unsigned int reg; 592d4ff816eSdavid.wu 593d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) { 594d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n"); 595d4ff816eSdavid.wu return; 596d4ff816eSdavid.wu } 597d4ff816eSdavid.wu 5988bdf63bdSDavid Wu reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 : 5998bdf63bdSDavid Wu RK3328_GRF_MAC_CON1; 6008bdf63bdSDavid Wu 601d4ff816eSdavid.wu if (speed == 10) 6028bdf63bdSDavid Wu regmap_write(bsp_priv->grf, reg, 603d4ff816eSdavid.wu RK3328_GMAC_RMII_CLK_2_5M | 604d4ff816eSdavid.wu RK3328_GMAC_SPEED_10M); 605d4ff816eSdavid.wu else if (speed == 100) 6068bdf63bdSDavid Wu regmap_write(bsp_priv->grf, reg, 607d4ff816eSdavid.wu RK3328_GMAC_RMII_CLK_25M | 608d4ff816eSdavid.wu RK3328_GMAC_SPEED_100M); 609d4ff816eSdavid.wu else 610d4ff816eSdavid.wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 611d4ff816eSdavid.wu } 612d4ff816eSdavid.wu 6138bdf63bdSDavid Wu static void rk3328_integrated_phy_powerup(struct rk_priv_data *priv) 6148bdf63bdSDavid Wu { 6158bdf63bdSDavid Wu regmap_write(priv->grf, RK3328_GRF_MACPHY_CON1, 6168bdf63bdSDavid Wu RK3328_MACPHY_RMII_MODE); 6178bdf63bdSDavid Wu } 6188bdf63bdSDavid Wu 619d4ff816eSdavid.wu static const struct rk_gmac_ops rk3328_ops = { 620d4ff816eSdavid.wu .set_to_rgmii = rk3328_set_to_rgmii, 621d4ff816eSdavid.wu .set_to_rmii = rk3328_set_to_rmii, 622d4ff816eSdavid.wu .set_rgmii_speed = rk3328_set_rgmii_speed, 623d4ff816eSdavid.wu .set_rmii_speed = rk3328_set_rmii_speed, 6248bdf63bdSDavid Wu .integrated_phy_powerup = rk3328_integrated_phy_powerup, 625d4ff816eSdavid.wu }; 626d4ff816eSdavid.wu 627ba289af8SRoger Chen #define RK3366_GRF_SOC_CON6 0x0418 628ba289af8SRoger Chen #define RK3366_GRF_SOC_CON7 0x041c 629ba289af8SRoger Chen 630ba289af8SRoger Chen /* RK3366_GRF_SOC_CON6 */ 631ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 632ba289af8SRoger Chen GRF_CLR_BIT(11)) 633ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 634ba289af8SRoger Chen GRF_BIT(11)) 635ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL GRF_BIT(8) 636ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 637ba289af8SRoger Chen #define RK3366_GMAC_SPEED_10M GRF_CLR_BIT(7) 638ba289af8SRoger Chen #define RK3366_GMAC_SPEED_100M GRF_BIT(7) 639ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_25M GRF_BIT(3) 640ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 641ba289af8SRoger Chen #define RK3366_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 642ba289af8SRoger Chen #define RK3366_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 643ba289af8SRoger Chen #define RK3366_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 644ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE GRF_BIT(6) 645ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 646ba289af8SRoger Chen 647ba289af8SRoger Chen /* RK3366_GRF_SOC_CON7 */ 648ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 649ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 650ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 651ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 652ba289af8SRoger Chen #define RK3366_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 653ba289af8SRoger Chen #define RK3366_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 654ba289af8SRoger Chen 655ba289af8SRoger Chen static void rk3366_set_to_rgmii(struct rk_priv_data *bsp_priv, 656ba289af8SRoger Chen int tx_delay, int rx_delay) 657ba289af8SRoger Chen { 658ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 659ba289af8SRoger Chen 660ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 661ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 662ba289af8SRoger Chen return; 663ba289af8SRoger Chen } 664ba289af8SRoger Chen 665ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 666ba289af8SRoger Chen RK3366_GMAC_PHY_INTF_SEL_RGMII | 667ba289af8SRoger Chen RK3366_GMAC_RMII_MODE_CLR); 668ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON7, 669eaf70ad1SWadim Egorov DELAY_ENABLE(RK3366, tx_delay, rx_delay) | 670ba289af8SRoger Chen RK3366_GMAC_CLK_RX_DL_CFG(rx_delay) | 671ba289af8SRoger Chen RK3366_GMAC_CLK_TX_DL_CFG(tx_delay)); 672ba289af8SRoger Chen } 673ba289af8SRoger Chen 674ba289af8SRoger Chen static void rk3366_set_to_rmii(struct rk_priv_data *bsp_priv) 675ba289af8SRoger Chen { 676ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 677ba289af8SRoger Chen 678ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 679ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 680ba289af8SRoger Chen return; 681ba289af8SRoger Chen } 682ba289af8SRoger Chen 683ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 684ba289af8SRoger Chen RK3366_GMAC_PHY_INTF_SEL_RMII | RK3366_GMAC_RMII_MODE); 685ba289af8SRoger Chen } 686ba289af8SRoger Chen 687ba289af8SRoger Chen static void rk3366_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 688ba289af8SRoger Chen { 689ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 690ba289af8SRoger Chen 691ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 692ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 693ba289af8SRoger Chen return; 694ba289af8SRoger Chen } 695ba289af8SRoger Chen 696ba289af8SRoger Chen if (speed == 10) 697ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 698ba289af8SRoger Chen RK3366_GMAC_CLK_2_5M); 699ba289af8SRoger Chen else if (speed == 100) 700ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 701ba289af8SRoger Chen RK3366_GMAC_CLK_25M); 702ba289af8SRoger Chen else if (speed == 1000) 703ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 704ba289af8SRoger Chen RK3366_GMAC_CLK_125M); 705ba289af8SRoger Chen else 706ba289af8SRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 707ba289af8SRoger Chen } 708ba289af8SRoger Chen 709ba289af8SRoger Chen static void rk3366_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 710ba289af8SRoger Chen { 711ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 712ba289af8SRoger Chen 713ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 714ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 715ba289af8SRoger Chen return; 716ba289af8SRoger Chen } 717ba289af8SRoger Chen 718ba289af8SRoger Chen if (speed == 10) { 719ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 720ba289af8SRoger Chen RK3366_GMAC_RMII_CLK_2_5M | 721ba289af8SRoger Chen RK3366_GMAC_SPEED_10M); 722ba289af8SRoger Chen } else if (speed == 100) { 723ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 724ba289af8SRoger Chen RK3366_GMAC_RMII_CLK_25M | 725ba289af8SRoger Chen RK3366_GMAC_SPEED_100M); 726ba289af8SRoger Chen } else { 727ba289af8SRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 728ba289af8SRoger Chen } 729ba289af8SRoger Chen } 730ba289af8SRoger Chen 731ba289af8SRoger Chen static const struct rk_gmac_ops rk3366_ops = { 732ba289af8SRoger Chen .set_to_rgmii = rk3366_set_to_rgmii, 733ba289af8SRoger Chen .set_to_rmii = rk3366_set_to_rmii, 734ba289af8SRoger Chen .set_rgmii_speed = rk3366_set_rgmii_speed, 735ba289af8SRoger Chen .set_rmii_speed = rk3366_set_rmii_speed, 736ba289af8SRoger Chen }; 737ba289af8SRoger Chen 738df558854SHeiko Stübner #define RK3368_GRF_SOC_CON15 0x043c 739df558854SHeiko Stübner #define RK3368_GRF_SOC_CON16 0x0440 740df558854SHeiko Stübner 741df558854SHeiko Stübner /* RK3368_GRF_SOC_CON15 */ 742df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 743df558854SHeiko Stübner GRF_CLR_BIT(11)) 744df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 745df558854SHeiko Stübner GRF_BIT(11)) 746df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL GRF_BIT(8) 747df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 748df558854SHeiko Stübner #define RK3368_GMAC_SPEED_10M GRF_CLR_BIT(7) 749df558854SHeiko Stübner #define RK3368_GMAC_SPEED_100M GRF_BIT(7) 750df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_25M GRF_BIT(3) 751df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 752df558854SHeiko Stübner #define RK3368_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 753df558854SHeiko Stübner #define RK3368_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 754df558854SHeiko Stübner #define RK3368_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 755df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE GRF_BIT(6) 756df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 757df558854SHeiko Stübner 758df558854SHeiko Stübner /* RK3368_GRF_SOC_CON16 */ 759df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 760df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 761df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 762df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 763df558854SHeiko Stübner #define RK3368_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 764df558854SHeiko Stübner #define RK3368_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 765df558854SHeiko Stübner 766df558854SHeiko Stübner static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv, 767df558854SHeiko Stübner int tx_delay, int rx_delay) 768df558854SHeiko Stübner { 769df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 770df558854SHeiko Stübner 771df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 772df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 773df558854SHeiko Stübner return; 774df558854SHeiko Stübner } 775df558854SHeiko Stübner 776df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 777df558854SHeiko Stübner RK3368_GMAC_PHY_INTF_SEL_RGMII | 778df558854SHeiko Stübner RK3368_GMAC_RMII_MODE_CLR); 779df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16, 780eaf70ad1SWadim Egorov DELAY_ENABLE(RK3368, tx_delay, rx_delay) | 781df558854SHeiko Stübner RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) | 782df558854SHeiko Stübner RK3368_GMAC_CLK_TX_DL_CFG(tx_delay)); 783df558854SHeiko Stübner } 784df558854SHeiko Stübner 785df558854SHeiko Stübner static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv) 786df558854SHeiko Stübner { 787df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 788df558854SHeiko Stübner 789df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 790df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 791df558854SHeiko Stübner return; 792df558854SHeiko Stübner } 793df558854SHeiko Stübner 794df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 795df558854SHeiko Stübner RK3368_GMAC_PHY_INTF_SEL_RMII | RK3368_GMAC_RMII_MODE); 796df558854SHeiko Stübner } 797df558854SHeiko Stübner 798df558854SHeiko Stübner static void rk3368_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 799df558854SHeiko Stübner { 800df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 801df558854SHeiko Stübner 802df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 803df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 804df558854SHeiko Stübner return; 805df558854SHeiko Stübner } 806df558854SHeiko Stübner 807df558854SHeiko Stübner if (speed == 10) 808df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 809df558854SHeiko Stübner RK3368_GMAC_CLK_2_5M); 810df558854SHeiko Stübner else if (speed == 100) 811df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 812df558854SHeiko Stübner RK3368_GMAC_CLK_25M); 813df558854SHeiko Stübner else if (speed == 1000) 814df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 815df558854SHeiko Stübner RK3368_GMAC_CLK_125M); 816df558854SHeiko Stübner else 817df558854SHeiko Stübner dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 818df558854SHeiko Stübner } 819df558854SHeiko Stübner 820df558854SHeiko Stübner static void rk3368_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 821df558854SHeiko Stübner { 822df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 823df558854SHeiko Stübner 824df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 825df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 826df558854SHeiko Stübner return; 827df558854SHeiko Stübner } 828df558854SHeiko Stübner 829df558854SHeiko Stübner if (speed == 10) { 830df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 831df558854SHeiko Stübner RK3368_GMAC_RMII_CLK_2_5M | 832df558854SHeiko Stübner RK3368_GMAC_SPEED_10M); 833df558854SHeiko Stübner } else if (speed == 100) { 834df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 835df558854SHeiko Stübner RK3368_GMAC_RMII_CLK_25M | 836df558854SHeiko Stübner RK3368_GMAC_SPEED_100M); 837df558854SHeiko Stübner } else { 838df558854SHeiko Stübner dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 839df558854SHeiko Stübner } 840df558854SHeiko Stübner } 841df558854SHeiko Stübner 84292c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3368_ops = { 843df558854SHeiko Stübner .set_to_rgmii = rk3368_set_to_rgmii, 844df558854SHeiko Stübner .set_to_rmii = rk3368_set_to_rmii, 845df558854SHeiko Stübner .set_rgmii_speed = rk3368_set_rgmii_speed, 846df558854SHeiko Stübner .set_rmii_speed = rk3368_set_rmii_speed, 847df558854SHeiko Stübner }; 848df558854SHeiko Stübner 849ba289af8SRoger Chen #define RK3399_GRF_SOC_CON5 0xc214 850ba289af8SRoger Chen #define RK3399_GRF_SOC_CON6 0xc218 851ba289af8SRoger Chen 852ba289af8SRoger Chen /* RK3399_GRF_SOC_CON5 */ 853ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 854ba289af8SRoger Chen GRF_CLR_BIT(11)) 855ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 856ba289af8SRoger Chen GRF_BIT(11)) 857ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL GRF_BIT(8) 858ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 859ba289af8SRoger Chen #define RK3399_GMAC_SPEED_10M GRF_CLR_BIT(7) 860ba289af8SRoger Chen #define RK3399_GMAC_SPEED_100M GRF_BIT(7) 861ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_25M GRF_BIT(3) 862ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 863ba289af8SRoger Chen #define RK3399_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 864ba289af8SRoger Chen #define RK3399_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 865ba289af8SRoger Chen #define RK3399_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 866ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE GRF_BIT(6) 867ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 868ba289af8SRoger Chen 869ba289af8SRoger Chen /* RK3399_GRF_SOC_CON6 */ 870ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 871ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 872ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 873ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 874ba289af8SRoger Chen #define RK3399_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 875ba289af8SRoger Chen #define RK3399_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 876ba289af8SRoger Chen 877ba289af8SRoger Chen static void rk3399_set_to_rgmii(struct rk_priv_data *bsp_priv, 878ba289af8SRoger Chen int tx_delay, int rx_delay) 879ba289af8SRoger Chen { 880ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 881ba289af8SRoger Chen 882ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 883ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 884ba289af8SRoger Chen return; 885ba289af8SRoger Chen } 886ba289af8SRoger Chen 887ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 888ba289af8SRoger Chen RK3399_GMAC_PHY_INTF_SEL_RGMII | 889ba289af8SRoger Chen RK3399_GMAC_RMII_MODE_CLR); 890ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON6, 891eaf70ad1SWadim Egorov DELAY_ENABLE(RK3399, tx_delay, rx_delay) | 892ba289af8SRoger Chen RK3399_GMAC_CLK_RX_DL_CFG(rx_delay) | 893ba289af8SRoger Chen RK3399_GMAC_CLK_TX_DL_CFG(tx_delay)); 894ba289af8SRoger Chen } 895ba289af8SRoger Chen 896ba289af8SRoger Chen static void rk3399_set_to_rmii(struct rk_priv_data *bsp_priv) 897ba289af8SRoger Chen { 898ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 899ba289af8SRoger Chen 900ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 901ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 902ba289af8SRoger Chen return; 903ba289af8SRoger Chen } 904ba289af8SRoger Chen 905ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 906ba289af8SRoger Chen RK3399_GMAC_PHY_INTF_SEL_RMII | RK3399_GMAC_RMII_MODE); 907ba289af8SRoger Chen } 908ba289af8SRoger Chen 909ba289af8SRoger Chen static void rk3399_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 910ba289af8SRoger Chen { 911ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 912ba289af8SRoger Chen 913ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 914ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 915ba289af8SRoger Chen return; 916ba289af8SRoger Chen } 917ba289af8SRoger Chen 918ba289af8SRoger Chen if (speed == 10) 919ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 920ba289af8SRoger Chen RK3399_GMAC_CLK_2_5M); 921ba289af8SRoger Chen else if (speed == 100) 922ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 923ba289af8SRoger Chen RK3399_GMAC_CLK_25M); 924ba289af8SRoger Chen else if (speed == 1000) 925ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 926ba289af8SRoger Chen RK3399_GMAC_CLK_125M); 927ba289af8SRoger Chen else 928ba289af8SRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 929ba289af8SRoger Chen } 930ba289af8SRoger Chen 931ba289af8SRoger Chen static void rk3399_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 932ba289af8SRoger Chen { 933ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 934ba289af8SRoger Chen 935ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 936ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 937ba289af8SRoger Chen return; 938ba289af8SRoger Chen } 939ba289af8SRoger Chen 940ba289af8SRoger Chen if (speed == 10) { 941ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 942ba289af8SRoger Chen RK3399_GMAC_RMII_CLK_2_5M | 943ba289af8SRoger Chen RK3399_GMAC_SPEED_10M); 944ba289af8SRoger Chen } else if (speed == 100) { 945ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 946ba289af8SRoger Chen RK3399_GMAC_RMII_CLK_25M | 947ba289af8SRoger Chen RK3399_GMAC_SPEED_100M); 948ba289af8SRoger Chen } else { 949ba289af8SRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 950ba289af8SRoger Chen } 951ba289af8SRoger Chen } 952ba289af8SRoger Chen 953ba289af8SRoger Chen static const struct rk_gmac_ops rk3399_ops = { 954ba289af8SRoger Chen .set_to_rgmii = rk3399_set_to_rgmii, 955ba289af8SRoger Chen .set_to_rmii = rk3399_set_to_rmii, 956ba289af8SRoger Chen .set_rgmii_speed = rk3399_set_rgmii_speed, 957ba289af8SRoger Chen .set_rmii_speed = rk3399_set_rmii_speed, 958ba289af8SRoger Chen }; 959ba289af8SRoger Chen 96089c9c163SDavid Wu #define RV1108_GRF_GMAC_CON0 0X0900 96189c9c163SDavid Wu 96289c9c163SDavid Wu /* RV1108_GRF_GMAC_CON0 */ 96389c9c163SDavid Wu #define RV1108_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \ 96489c9c163SDavid Wu GRF_BIT(6)) 96589c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL GRF_BIT(3) 96689c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 96789c9c163SDavid Wu #define RV1108_GMAC_SPEED_10M GRF_CLR_BIT(2) 96889c9c163SDavid Wu #define RV1108_GMAC_SPEED_100M GRF_BIT(2) 96989c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_25M GRF_BIT(7) 97089c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7) 97189c9c163SDavid Wu 97289c9c163SDavid Wu static void rv1108_set_to_rmii(struct rk_priv_data *bsp_priv) 97389c9c163SDavid Wu { 97489c9c163SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 97589c9c163SDavid Wu 97689c9c163SDavid Wu if (IS_ERR(bsp_priv->grf)) { 97789c9c163SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 97889c9c163SDavid Wu return; 97989c9c163SDavid Wu } 98089c9c163SDavid Wu 98189c9c163SDavid Wu regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0, 98289c9c163SDavid Wu RV1108_GMAC_PHY_INTF_SEL_RMII); 98389c9c163SDavid Wu } 98489c9c163SDavid Wu 98589c9c163SDavid Wu static void rv1108_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 98689c9c163SDavid Wu { 98789c9c163SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 98889c9c163SDavid Wu 98989c9c163SDavid Wu if (IS_ERR(bsp_priv->grf)) { 99089c9c163SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 99189c9c163SDavid Wu return; 99289c9c163SDavid Wu } 99389c9c163SDavid Wu 99489c9c163SDavid Wu if (speed == 10) { 99589c9c163SDavid Wu regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0, 99689c9c163SDavid Wu RV1108_GMAC_RMII_CLK_2_5M | 99789c9c163SDavid Wu RV1108_GMAC_SPEED_10M); 99889c9c163SDavid Wu } else if (speed == 100) { 99989c9c163SDavid Wu regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0, 100089c9c163SDavid Wu RV1108_GMAC_RMII_CLK_25M | 100189c9c163SDavid Wu RV1108_GMAC_SPEED_100M); 100289c9c163SDavid Wu } else { 100389c9c163SDavid Wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 100489c9c163SDavid Wu } 100589c9c163SDavid Wu } 100689c9c163SDavid Wu 100789c9c163SDavid Wu static const struct rk_gmac_ops rv1108_ops = { 100889c9c163SDavid Wu .set_to_rmii = rv1108_set_to_rmii, 100989c9c163SDavid Wu .set_rmii_speed = rv1108_set_rmii_speed, 101089c9c163SDavid Wu }; 101189c9c163SDavid Wu 1012fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON0 0xb00 1013fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON1 0xb04 1014fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON2 0xb08 1015fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON3 0xb0c 1016fecd4d7eSDavid Wu 1017fecd4d7eSDavid Wu #define RK_MACPHY_ENABLE GRF_BIT(0) 1018fecd4d7eSDavid Wu #define RK_MACPHY_DISABLE GRF_CLR_BIT(0) 1019fecd4d7eSDavid Wu #define RK_MACPHY_CFG_CLK_50M GRF_BIT(14) 1020fecd4d7eSDavid Wu #define RK_GMAC2PHY_RMII_MODE (GRF_BIT(6) | GRF_CLR_BIT(7)) 1021fecd4d7eSDavid Wu #define RK_GRF_CON2_MACPHY_ID HIWORD_UPDATE(0x1234, 0xffff, 0) 1022fecd4d7eSDavid Wu #define RK_GRF_CON3_MACPHY_ID HIWORD_UPDATE(0x35, 0x3f, 0) 1023fecd4d7eSDavid Wu 1024fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerup(struct rk_priv_data *priv) 10257ad269eaSRoger Chen { 1026fecd4d7eSDavid Wu if (priv->ops->integrated_phy_powerup) 1027fecd4d7eSDavid Wu priv->ops->integrated_phy_powerup(priv); 1028fecd4d7eSDavid Wu 1029fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M); 1030fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE); 1031fecd4d7eSDavid Wu 1032fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID); 1033fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID); 1034fecd4d7eSDavid Wu 1035fecd4d7eSDavid Wu if (priv->phy_reset) { 1036fecd4d7eSDavid Wu /* PHY needs to be disabled before trying to reset it */ 1037fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE); 1038fecd4d7eSDavid Wu if (priv->phy_reset) 1039fecd4d7eSDavid Wu reset_control_assert(priv->phy_reset); 1040fecd4d7eSDavid Wu usleep_range(10, 20); 1041fecd4d7eSDavid Wu if (priv->phy_reset) 1042fecd4d7eSDavid Wu reset_control_deassert(priv->phy_reset); 1043fecd4d7eSDavid Wu usleep_range(10, 20); 1044fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE); 1045fecd4d7eSDavid Wu msleep(30); 1046fecd4d7eSDavid Wu } 1047fecd4d7eSDavid Wu } 1048fecd4d7eSDavid Wu 1049fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerdown(struct rk_priv_data *priv) 1050fecd4d7eSDavid Wu { 1051fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE); 1052fecd4d7eSDavid Wu if (priv->phy_reset) 1053fecd4d7eSDavid Wu reset_control_assert(priv->phy_reset); 1054fecd4d7eSDavid Wu } 1055fecd4d7eSDavid Wu 1056fecd4d7eSDavid Wu static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat) 1057fecd4d7eSDavid Wu { 1058fecd4d7eSDavid Wu struct rk_priv_data *bsp_priv = plat->bsp_priv; 10597ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 1060fecd4d7eSDavid Wu int ret; 10617ad269eaSRoger Chen 10627ad269eaSRoger Chen bsp_priv->clk_enabled = false; 10637ad269eaSRoger Chen 10647ad269eaSRoger Chen bsp_priv->mac_clk_rx = devm_clk_get(dev, "mac_clk_rx"); 10657ad269eaSRoger Chen if (IS_ERR(bsp_priv->mac_clk_rx)) 1066d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1067d42202dcSRomain Perier "mac_clk_rx"); 10687ad269eaSRoger Chen 10697ad269eaSRoger Chen bsp_priv->mac_clk_tx = devm_clk_get(dev, "mac_clk_tx"); 10707ad269eaSRoger Chen if (IS_ERR(bsp_priv->mac_clk_tx)) 1071d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1072d42202dcSRomain Perier "mac_clk_tx"); 10737ad269eaSRoger Chen 10747ad269eaSRoger Chen bsp_priv->aclk_mac = devm_clk_get(dev, "aclk_mac"); 10757ad269eaSRoger Chen if (IS_ERR(bsp_priv->aclk_mac)) 1076d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1077d42202dcSRomain Perier "aclk_mac"); 10787ad269eaSRoger Chen 10797ad269eaSRoger Chen bsp_priv->pclk_mac = devm_clk_get(dev, "pclk_mac"); 10807ad269eaSRoger Chen if (IS_ERR(bsp_priv->pclk_mac)) 1081d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1082d42202dcSRomain Perier "pclk_mac"); 10837ad269eaSRoger Chen 10847ad269eaSRoger Chen bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth"); 10857ad269eaSRoger Chen if (IS_ERR(bsp_priv->clk_mac)) 1086d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1087d42202dcSRomain Perier "stmmaceth"); 10887ad269eaSRoger Chen 10897ad269eaSRoger Chen if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) { 10907ad269eaSRoger Chen bsp_priv->clk_mac_ref = devm_clk_get(dev, "clk_mac_ref"); 10917ad269eaSRoger Chen if (IS_ERR(bsp_priv->clk_mac_ref)) 1092d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1093d42202dcSRomain Perier "clk_mac_ref"); 10947ad269eaSRoger Chen 10957ad269eaSRoger Chen if (!bsp_priv->clock_input) { 10967ad269eaSRoger Chen bsp_priv->clk_mac_refout = 10977ad269eaSRoger Chen devm_clk_get(dev, "clk_mac_refout"); 10987ad269eaSRoger Chen if (IS_ERR(bsp_priv->clk_mac_refout)) 1099d42202dcSRomain Perier dev_err(dev, "cannot get clock %s\n", 1100d42202dcSRomain Perier "clk_mac_refout"); 11017ad269eaSRoger Chen } 11027ad269eaSRoger Chen } 11037ad269eaSRoger Chen 110423c94d63SDavid Wu bsp_priv->clk_mac_speed = devm_clk_get(dev, "clk_mac_speed"); 110523c94d63SDavid Wu if (IS_ERR(bsp_priv->clk_mac_speed)) 110623c94d63SDavid Wu dev_err(dev, "cannot get clock %s\n", "clk_mac_speed"); 110723c94d63SDavid Wu 11087ad269eaSRoger Chen if (bsp_priv->clock_input) { 1109d42202dcSRomain Perier dev_info(dev, "clock input from PHY\n"); 11107ad269eaSRoger Chen } else { 11117ad269eaSRoger Chen if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) 1112c48fa33cSHeiko Stübner clk_set_rate(bsp_priv->clk_mac, 50000000); 11137ad269eaSRoger Chen } 11147ad269eaSRoger Chen 1115fecd4d7eSDavid Wu if (plat->phy_node && bsp_priv->integrated_phy) { 1116fecd4d7eSDavid Wu bsp_priv->clk_phy = of_clk_get(plat->phy_node, 0); 1117fecd4d7eSDavid Wu if (IS_ERR(bsp_priv->clk_phy)) { 1118fecd4d7eSDavid Wu ret = PTR_ERR(bsp_priv->clk_phy); 1119fecd4d7eSDavid Wu dev_err(dev, "Cannot get PHY clock: %d\n", ret); 1120fecd4d7eSDavid Wu return -EINVAL; 1121fecd4d7eSDavid Wu } 1122fecd4d7eSDavid Wu clk_set_rate(bsp_priv->clk_phy, 50000000); 1123fecd4d7eSDavid Wu } 1124fecd4d7eSDavid Wu 11257ad269eaSRoger Chen return 0; 11267ad269eaSRoger Chen } 11277ad269eaSRoger Chen 11287ad269eaSRoger Chen static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable) 11297ad269eaSRoger Chen { 1130428ad1bcSLABBE Corentin int phy_iface = bsp_priv->phy_iface; 11317ad269eaSRoger Chen 11327ad269eaSRoger Chen if (enable) { 11337ad269eaSRoger Chen if (!bsp_priv->clk_enabled) { 11347ad269eaSRoger Chen if (phy_iface == PHY_INTERFACE_MODE_RMII) { 11357ad269eaSRoger Chen if (!IS_ERR(bsp_priv->mac_clk_rx)) 11367ad269eaSRoger Chen clk_prepare_enable( 11377ad269eaSRoger Chen bsp_priv->mac_clk_rx); 11387ad269eaSRoger Chen 11397ad269eaSRoger Chen if (!IS_ERR(bsp_priv->clk_mac_ref)) 11407ad269eaSRoger Chen clk_prepare_enable( 11417ad269eaSRoger Chen bsp_priv->clk_mac_ref); 11427ad269eaSRoger Chen 11437ad269eaSRoger Chen if (!IS_ERR(bsp_priv->clk_mac_refout)) 11447ad269eaSRoger Chen clk_prepare_enable( 11457ad269eaSRoger Chen bsp_priv->clk_mac_refout); 11467ad269eaSRoger Chen } 11477ad269eaSRoger Chen 1148fecd4d7eSDavid Wu if (!IS_ERR(bsp_priv->clk_phy)) 1149fecd4d7eSDavid Wu clk_prepare_enable(bsp_priv->clk_phy); 1150fecd4d7eSDavid Wu 11517ad269eaSRoger Chen if (!IS_ERR(bsp_priv->aclk_mac)) 11527ad269eaSRoger Chen clk_prepare_enable(bsp_priv->aclk_mac); 11537ad269eaSRoger Chen 11547ad269eaSRoger Chen if (!IS_ERR(bsp_priv->pclk_mac)) 11557ad269eaSRoger Chen clk_prepare_enable(bsp_priv->pclk_mac); 11567ad269eaSRoger Chen 11577ad269eaSRoger Chen if (!IS_ERR(bsp_priv->mac_clk_tx)) 11587ad269eaSRoger Chen clk_prepare_enable(bsp_priv->mac_clk_tx); 11597ad269eaSRoger Chen 116023c94d63SDavid Wu if (!IS_ERR(bsp_priv->clk_mac_speed)) 116123c94d63SDavid Wu clk_prepare_enable(bsp_priv->clk_mac_speed); 116223c94d63SDavid Wu 11637ad269eaSRoger Chen /** 11647ad269eaSRoger Chen * if (!IS_ERR(bsp_priv->clk_mac)) 11657ad269eaSRoger Chen * clk_prepare_enable(bsp_priv->clk_mac); 11667ad269eaSRoger Chen */ 11677ad269eaSRoger Chen mdelay(5); 11687ad269eaSRoger Chen bsp_priv->clk_enabled = true; 11697ad269eaSRoger Chen } 11707ad269eaSRoger Chen } else { 11717ad269eaSRoger Chen if (bsp_priv->clk_enabled) { 11727ad269eaSRoger Chen if (phy_iface == PHY_INTERFACE_MODE_RMII) { 117393120ebaSYueHaibing clk_disable_unprepare(bsp_priv->mac_clk_rx); 11747ad269eaSRoger Chen 117593120ebaSYueHaibing clk_disable_unprepare(bsp_priv->clk_mac_ref); 11767ad269eaSRoger Chen 117793120ebaSYueHaibing clk_disable_unprepare(bsp_priv->clk_mac_refout); 11787ad269eaSRoger Chen } 11797ad269eaSRoger Chen 1180fecd4d7eSDavid Wu clk_disable_unprepare(bsp_priv->clk_phy); 1181fecd4d7eSDavid Wu 11827ad269eaSRoger Chen clk_disable_unprepare(bsp_priv->aclk_mac); 11837ad269eaSRoger Chen 11847ad269eaSRoger Chen clk_disable_unprepare(bsp_priv->pclk_mac); 11857ad269eaSRoger Chen 11867ad269eaSRoger Chen clk_disable_unprepare(bsp_priv->mac_clk_tx); 118723c94d63SDavid Wu 118823c94d63SDavid Wu clk_disable_unprepare(bsp_priv->clk_mac_speed); 11897ad269eaSRoger Chen /** 11907ad269eaSRoger Chen * if (!IS_ERR(bsp_priv->clk_mac)) 11917ad269eaSRoger Chen * clk_disable_unprepare(bsp_priv->clk_mac); 11927ad269eaSRoger Chen */ 11937ad269eaSRoger Chen bsp_priv->clk_enabled = false; 11947ad269eaSRoger Chen } 11957ad269eaSRoger Chen } 11967ad269eaSRoger Chen 11977ad269eaSRoger Chen return 0; 11987ad269eaSRoger Chen } 11997ad269eaSRoger Chen 12007ad269eaSRoger Chen static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable) 12017ad269eaSRoger Chen { 12022e12f536SRomain Perier struct regulator *ldo = bsp_priv->regulator; 12037ad269eaSRoger Chen int ret; 12047ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 12057ad269eaSRoger Chen 12062e12f536SRomain Perier if (!ldo) { 1207d42202dcSRomain Perier dev_err(dev, "no regulator found\n"); 12087ad269eaSRoger Chen return -1; 12097ad269eaSRoger Chen } 12107ad269eaSRoger Chen 12117ad269eaSRoger Chen if (enable) { 12127ad269eaSRoger Chen ret = regulator_enable(ldo); 12132e12f536SRomain Perier if (ret) 1214d42202dcSRomain Perier dev_err(dev, "fail to enable phy-supply\n"); 12157ad269eaSRoger Chen } else { 12167ad269eaSRoger Chen ret = regulator_disable(ldo); 12172e12f536SRomain Perier if (ret) 1218d42202dcSRomain Perier dev_err(dev, "fail to disable phy-supply\n"); 12197ad269eaSRoger Chen } 12207ad269eaSRoger Chen 12217ad269eaSRoger Chen return 0; 12227ad269eaSRoger Chen } 12237ad269eaSRoger Chen 12240fb98db1SHeiko Stübner static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev, 1225fecd4d7eSDavid Wu struct plat_stmmacenet_data *plat, 122692c2588fSJoachim Eastwood const struct rk_gmac_ops *ops) 12277ad269eaSRoger Chen { 12287ad269eaSRoger Chen struct rk_priv_data *bsp_priv; 12297ad269eaSRoger Chen struct device *dev = &pdev->dev; 12307ad269eaSRoger Chen int ret; 12317ad269eaSRoger Chen const char *strings = NULL; 12327ad269eaSRoger Chen int value; 12337ad269eaSRoger Chen 12347ad269eaSRoger Chen bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL); 12357ad269eaSRoger Chen if (!bsp_priv) 12367ad269eaSRoger Chen return ERR_PTR(-ENOMEM); 12377ad269eaSRoger Chen 12387ad269eaSRoger Chen bsp_priv->phy_iface = of_get_phy_mode(dev->of_node); 12390fb98db1SHeiko Stübner bsp_priv->ops = ops; 12407ad269eaSRoger Chen 12412e12f536SRomain Perier bsp_priv->regulator = devm_regulator_get_optional(dev, "phy"); 12422e12f536SRomain Perier if (IS_ERR(bsp_priv->regulator)) { 12432e12f536SRomain Perier if (PTR_ERR(bsp_priv->regulator) == -EPROBE_DEFER) { 12442e12f536SRomain Perier dev_err(dev, "phy regulator is not available yet, deferred probing\n"); 12452e12f536SRomain Perier return ERR_PTR(-EPROBE_DEFER); 12462e12f536SRomain Perier } 12472e12f536SRomain Perier dev_err(dev, "no regulator found\n"); 12482e12f536SRomain Perier bsp_priv->regulator = NULL; 12497ad269eaSRoger Chen } 12507ad269eaSRoger Chen 12517ad269eaSRoger Chen ret = of_property_read_string(dev->of_node, "clock_in_out", &strings); 12527ad269eaSRoger Chen if (ret) { 1253d42202dcSRomain Perier dev_err(dev, "Can not read property: clock_in_out.\n"); 12547ad269eaSRoger Chen bsp_priv->clock_input = true; 12557ad269eaSRoger Chen } else { 1256d42202dcSRomain Perier dev_info(dev, "clock input or output? (%s).\n", 1257d42202dcSRomain Perier strings); 12587ad269eaSRoger Chen if (!strcmp(strings, "input")) 12597ad269eaSRoger Chen bsp_priv->clock_input = true; 12607ad269eaSRoger Chen else 12617ad269eaSRoger Chen bsp_priv->clock_input = false; 12627ad269eaSRoger Chen } 12637ad269eaSRoger Chen 12647ad269eaSRoger Chen ret = of_property_read_u32(dev->of_node, "tx_delay", &value); 12657ad269eaSRoger Chen if (ret) { 12667ad269eaSRoger Chen bsp_priv->tx_delay = 0x30; 1267d42202dcSRomain Perier dev_err(dev, "Can not read property: tx_delay."); 1268d42202dcSRomain Perier dev_err(dev, "set tx_delay to 0x%x\n", 1269d42202dcSRomain Perier bsp_priv->tx_delay); 12707ad269eaSRoger Chen } else { 1271d42202dcSRomain Perier dev_info(dev, "TX delay(0x%x).\n", value); 12727ad269eaSRoger Chen bsp_priv->tx_delay = value; 12737ad269eaSRoger Chen } 12747ad269eaSRoger Chen 12757ad269eaSRoger Chen ret = of_property_read_u32(dev->of_node, "rx_delay", &value); 12767ad269eaSRoger Chen if (ret) { 12777ad269eaSRoger Chen bsp_priv->rx_delay = 0x10; 1278d42202dcSRomain Perier dev_err(dev, "Can not read property: rx_delay."); 1279d42202dcSRomain Perier dev_err(dev, "set rx_delay to 0x%x\n", 1280d42202dcSRomain Perier bsp_priv->rx_delay); 12817ad269eaSRoger Chen } else { 1282d42202dcSRomain Perier dev_info(dev, "RX delay(0x%x).\n", value); 12837ad269eaSRoger Chen bsp_priv->rx_delay = value; 12847ad269eaSRoger Chen } 12857ad269eaSRoger Chen 12867ad269eaSRoger Chen bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node, 12877ad269eaSRoger Chen "rockchip,grf"); 12887ad269eaSRoger Chen 1289fecd4d7eSDavid Wu if (plat->phy_node) { 1290fecd4d7eSDavid Wu bsp_priv->integrated_phy = of_property_read_bool(plat->phy_node, 1291fecd4d7eSDavid Wu "phy-is-integrated"); 1292fecd4d7eSDavid Wu if (bsp_priv->integrated_phy) { 1293fecd4d7eSDavid Wu bsp_priv->phy_reset = of_reset_control_get(plat->phy_node, NULL); 1294fecd4d7eSDavid Wu if (IS_ERR(bsp_priv->phy_reset)) { 1295fecd4d7eSDavid Wu dev_err(&pdev->dev, "No PHY reset control found.\n"); 1296fecd4d7eSDavid Wu bsp_priv->phy_reset = NULL; 1297fecd4d7eSDavid Wu } 1298fecd4d7eSDavid Wu } 1299fecd4d7eSDavid Wu } 1300fecd4d7eSDavid Wu dev_info(dev, "integrated PHY? (%s).\n", 1301fecd4d7eSDavid Wu bsp_priv->integrated_phy ? "yes" : "no"); 1302fecd4d7eSDavid Wu 1303fecd4d7eSDavid Wu bsp_priv->pdev = pdev; 130445383f52SRoger Chen 130545383f52SRoger Chen return bsp_priv; 130645383f52SRoger Chen } 130745383f52SRoger Chen 130845383f52SRoger Chen static int rk_gmac_powerup(struct rk_priv_data *bsp_priv) 130945383f52SRoger Chen { 131045383f52SRoger Chen int ret; 131145383f52SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 131245383f52SRoger Chen 1313f217bfdeSHeiko Stübner ret = gmac_clk_enable(bsp_priv, true); 1314f217bfdeSHeiko Stübner if (ret) 1315f217bfdeSHeiko Stübner return ret; 1316f217bfdeSHeiko Stübner 13177ad269eaSRoger Chen /*rmii or rgmii*/ 1318eaf70ad1SWadim Egorov switch (bsp_priv->phy_iface) { 1319eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII: 1320d42202dcSRomain Perier dev_info(dev, "init for RGMII\n"); 13210fb98db1SHeiko Stübner bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 13220fb98db1SHeiko Stübner bsp_priv->rx_delay); 1323eaf70ad1SWadim Egorov break; 1324eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_ID: 1325eaf70ad1SWadim Egorov dev_info(dev, "init for RGMII_ID\n"); 1326eaf70ad1SWadim Egorov bsp_priv->ops->set_to_rgmii(bsp_priv, 0, 0); 1327eaf70ad1SWadim Egorov break; 1328eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_RXID: 1329eaf70ad1SWadim Egorov dev_info(dev, "init for RGMII_RXID\n"); 1330eaf70ad1SWadim Egorov bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 0); 1331eaf70ad1SWadim Egorov break; 1332eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_TXID: 1333eaf70ad1SWadim Egorov dev_info(dev, "init for RGMII_TXID\n"); 1334eaf70ad1SWadim Egorov bsp_priv->ops->set_to_rgmii(bsp_priv, 0, bsp_priv->rx_delay); 1335eaf70ad1SWadim Egorov break; 1336eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RMII: 1337d42202dcSRomain Perier dev_info(dev, "init for RMII\n"); 13380fb98db1SHeiko Stübner bsp_priv->ops->set_to_rmii(bsp_priv); 1339eaf70ad1SWadim Egorov break; 1340eaf70ad1SWadim Egorov default: 1341d42202dcSRomain Perier dev_err(dev, "NO interface defined!\n"); 13427ad269eaSRoger Chen } 13437ad269eaSRoger Chen 13447ad269eaSRoger Chen ret = phy_power_on(bsp_priv, true); 1345*c69c29a1SAlexey Khoroshilov if (ret) { 1346*c69c29a1SAlexey Khoroshilov gmac_clk_enable(bsp_priv, false); 13477ad269eaSRoger Chen return ret; 1348*c69c29a1SAlexey Khoroshilov } 13497ad269eaSRoger Chen 13502c896fb0SDavid Wu pm_runtime_enable(dev); 13512c896fb0SDavid Wu pm_runtime_get_sync(dev); 13522c896fb0SDavid Wu 1353fecd4d7eSDavid Wu if (bsp_priv->integrated_phy) 1354fecd4d7eSDavid Wu rk_gmac_integrated_phy_powerup(bsp_priv); 1355fecd4d7eSDavid Wu 13567ad269eaSRoger Chen return 0; 13577ad269eaSRoger Chen } 13587ad269eaSRoger Chen 1359229666c1SVincent Palatin static void rk_gmac_powerdown(struct rk_priv_data *gmac) 13607ad269eaSRoger Chen { 13612c896fb0SDavid Wu struct device *dev = &gmac->pdev->dev; 13622c896fb0SDavid Wu 1363fecd4d7eSDavid Wu if (gmac->integrated_phy) 1364fecd4d7eSDavid Wu rk_gmac_integrated_phy_powerdown(gmac); 1365fecd4d7eSDavid Wu 13662c896fb0SDavid Wu pm_runtime_put_sync(dev); 13672c896fb0SDavid Wu pm_runtime_disable(dev); 13682c896fb0SDavid Wu 13697ad269eaSRoger Chen phy_power_on(gmac, false); 13707ad269eaSRoger Chen gmac_clk_enable(gmac, false); 13717ad269eaSRoger Chen } 13727ad269eaSRoger Chen 13737ad269eaSRoger Chen static void rk_fix_speed(void *priv, unsigned int speed) 13747ad269eaSRoger Chen { 13757ad269eaSRoger Chen struct rk_priv_data *bsp_priv = priv; 13767ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 13777ad269eaSRoger Chen 1378eaf70ad1SWadim Egorov switch (bsp_priv->phy_iface) { 1379eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII: 1380eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_ID: 1381eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_RXID: 1382eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_TXID: 13830fb98db1SHeiko Stübner bsp_priv->ops->set_rgmii_speed(bsp_priv, speed); 1384eaf70ad1SWadim Egorov break; 1385eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RMII: 13860fb98db1SHeiko Stübner bsp_priv->ops->set_rmii_speed(bsp_priv, speed); 1387eaf70ad1SWadim Egorov break; 1388eaf70ad1SWadim Egorov default: 13897ad269eaSRoger Chen dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface); 13907ad269eaSRoger Chen } 1391eaf70ad1SWadim Egorov } 13927ad269eaSRoger Chen 139327ffefd2SJoachim Eastwood static int rk_gmac_probe(struct platform_device *pdev) 139427ffefd2SJoachim Eastwood { 139527ffefd2SJoachim Eastwood struct plat_stmmacenet_data *plat_dat; 139627ffefd2SJoachim Eastwood struct stmmac_resources stmmac_res; 1397f529f182SJoachim Eastwood const struct rk_gmac_ops *data; 139827ffefd2SJoachim Eastwood int ret; 139927ffefd2SJoachim Eastwood 1400149adeddSJoachim Eastwood data = of_device_get_match_data(&pdev->dev); 1401149adeddSJoachim Eastwood if (!data) { 1402149adeddSJoachim Eastwood dev_err(&pdev->dev, "no of match data provided\n"); 1403149adeddSJoachim Eastwood return -EINVAL; 1404149adeddSJoachim Eastwood } 1405149adeddSJoachim Eastwood 140627ffefd2SJoachim Eastwood ret = stmmac_get_platform_resources(pdev, &stmmac_res); 140727ffefd2SJoachim Eastwood if (ret) 140827ffefd2SJoachim Eastwood return ret; 140927ffefd2SJoachim Eastwood 141027ffefd2SJoachim Eastwood plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac); 141127ffefd2SJoachim Eastwood if (IS_ERR(plat_dat)) 141227ffefd2SJoachim Eastwood return PTR_ERR(plat_dat); 141327ffefd2SJoachim Eastwood 141427ffefd2SJoachim Eastwood plat_dat->has_gmac = true; 141527ffefd2SJoachim Eastwood plat_dat->fix_mac_speed = rk_fix_speed; 141627ffefd2SJoachim Eastwood 1417fecd4d7eSDavid Wu plat_dat->bsp_priv = rk_gmac_setup(pdev, plat_dat, data); 1418d2ed0a77SJohan Hovold if (IS_ERR(plat_dat->bsp_priv)) { 1419d2ed0a77SJohan Hovold ret = PTR_ERR(plat_dat->bsp_priv); 1420d2ed0a77SJohan Hovold goto err_remove_config_dt; 1421d2ed0a77SJohan Hovold } 142227ffefd2SJoachim Eastwood 1423fecd4d7eSDavid Wu ret = rk_gmac_clk_init(plat_dat); 1424fecd4d7eSDavid Wu if (ret) 1425fecd4d7eSDavid Wu return ret; 1426fecd4d7eSDavid Wu 142707a5e769SJoachim Eastwood ret = rk_gmac_powerup(plat_dat->bsp_priv); 142827ffefd2SJoachim Eastwood if (ret) 1429d2ed0a77SJohan Hovold goto err_remove_config_dt; 143027ffefd2SJoachim Eastwood 14312d222656SJohan Hovold ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); 14322d222656SJohan Hovold if (ret) 14332745529aSDavid S. Miller goto err_gmac_powerdown; 14342d222656SJohan Hovold 14352d222656SJohan Hovold return 0; 14362d222656SJohan Hovold 14372745529aSDavid S. Miller err_gmac_powerdown: 14382745529aSDavid S. Miller rk_gmac_powerdown(plat_dat->bsp_priv); 1439d2ed0a77SJohan Hovold err_remove_config_dt: 1440d2ed0a77SJohan Hovold stmmac_remove_config_dt(pdev, plat_dat); 14412d222656SJohan Hovold 14422d222656SJohan Hovold return ret; 144327ffefd2SJoachim Eastwood } 144427ffefd2SJoachim Eastwood 14450de8c4c9SJoachim Eastwood static int rk_gmac_remove(struct platform_device *pdev) 14460de8c4c9SJoachim Eastwood { 14470de8c4c9SJoachim Eastwood struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(&pdev->dev); 14480de8c4c9SJoachim Eastwood int ret = stmmac_dvr_remove(&pdev->dev); 14490de8c4c9SJoachim Eastwood 14500de8c4c9SJoachim Eastwood rk_gmac_powerdown(bsp_priv); 14510de8c4c9SJoachim Eastwood 14520de8c4c9SJoachim Eastwood return ret; 14530de8c4c9SJoachim Eastwood } 14540de8c4c9SJoachim Eastwood 14555619468aSJoachim Eastwood #ifdef CONFIG_PM_SLEEP 14565619468aSJoachim Eastwood static int rk_gmac_suspend(struct device *dev) 14575619468aSJoachim Eastwood { 14585619468aSJoachim Eastwood struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev); 14595619468aSJoachim Eastwood int ret = stmmac_suspend(dev); 14605619468aSJoachim Eastwood 14615619468aSJoachim Eastwood /* Keep the PHY up if we use Wake-on-Lan. */ 14625619468aSJoachim Eastwood if (!device_may_wakeup(dev)) { 14635619468aSJoachim Eastwood rk_gmac_powerdown(bsp_priv); 14645619468aSJoachim Eastwood bsp_priv->suspended = true; 14655619468aSJoachim Eastwood } 14665619468aSJoachim Eastwood 14675619468aSJoachim Eastwood return ret; 14685619468aSJoachim Eastwood } 14695619468aSJoachim Eastwood 14705619468aSJoachim Eastwood static int rk_gmac_resume(struct device *dev) 14715619468aSJoachim Eastwood { 14725619468aSJoachim Eastwood struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev); 14735619468aSJoachim Eastwood 14745619468aSJoachim Eastwood /* The PHY was up for Wake-on-Lan. */ 14755619468aSJoachim Eastwood if (bsp_priv->suspended) { 14765619468aSJoachim Eastwood rk_gmac_powerup(bsp_priv); 14775619468aSJoachim Eastwood bsp_priv->suspended = false; 14785619468aSJoachim Eastwood } 14795619468aSJoachim Eastwood 14805619468aSJoachim Eastwood return stmmac_resume(dev); 14815619468aSJoachim Eastwood } 14825619468aSJoachim Eastwood #endif /* CONFIG_PM_SLEEP */ 14835619468aSJoachim Eastwood 14845619468aSJoachim Eastwood static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume); 14855619468aSJoachim Eastwood 1486e0fb4013SJoachim Eastwood static const struct of_device_id rk_gmac_dwmac_match[] = { 148723c94d63SDavid Wu { .compatible = "rockchip,px30-gmac", .data = &px30_ops }, 148805946876SDavid Wu { .compatible = "rockchip,rk3128-gmac", .data = &rk3128_ops }, 1489e7ffd812SXing Zheng { .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops }, 1490f529f182SJoachim Eastwood { .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops }, 1491d4ff816eSdavid.wu { .compatible = "rockchip,rk3328-gmac", .data = &rk3328_ops }, 1492ba289af8SRoger Chen { .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops }, 1493f529f182SJoachim Eastwood { .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops }, 1494ba289af8SRoger Chen { .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops }, 149589c9c163SDavid Wu { .compatible = "rockchip,rv1108-gmac", .data = &rv1108_ops }, 1496e0fb4013SJoachim Eastwood { } 1497e0fb4013SJoachim Eastwood }; 1498e0fb4013SJoachim Eastwood MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match); 1499e0fb4013SJoachim Eastwood 1500e0fb4013SJoachim Eastwood static struct platform_driver rk_gmac_dwmac_driver = { 150127ffefd2SJoachim Eastwood .probe = rk_gmac_probe, 15020de8c4c9SJoachim Eastwood .remove = rk_gmac_remove, 1503e0fb4013SJoachim Eastwood .driver = { 1504e0fb4013SJoachim Eastwood .name = "rk_gmac-dwmac", 15055619468aSJoachim Eastwood .pm = &rk_gmac_pm_ops, 1506e0fb4013SJoachim Eastwood .of_match_table = rk_gmac_dwmac_match, 1507e0fb4013SJoachim Eastwood }, 1508e0fb4013SJoachim Eastwood }; 1509e0fb4013SJoachim Eastwood module_platform_driver(rk_gmac_dwmac_driver); 1510e0fb4013SJoachim Eastwood 1511e0fb4013SJoachim Eastwood MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>"); 1512e0fb4013SJoachim Eastwood MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer"); 1513e0fb4013SJoachim Eastwood MODULE_LICENSE("GPL"); 1514