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> 15e0fb4013SJoachim Eastwood #include <linux/module.h> 163d40aed8SRob Herring #include <linux/of.h> 17e0fb4013SJoachim Eastwood #include <linux/platform_device.h> 187ad269eaSRoger Chen #include <linux/regulator/consumer.h> 197ad269eaSRoger Chen #include <linux/delay.h> 207ad269eaSRoger Chen #include <linux/mfd/syscon.h> 217ad269eaSRoger Chen #include <linux/regmap.h> 22aec3f415SPunit Agrawal #include <linux/pm_runtime.h> 237ad269eaSRoger Chen 24e0fb4013SJoachim Eastwood #include "stmmac_platform.h" 25e0fb4013SJoachim Eastwood 260fb98db1SHeiko Stübner struct rk_priv_data; 270fb98db1SHeiko Stübner struct rk_gmac_ops { 280fb98db1SHeiko Stübner void (*set_to_rgmii)(struct rk_priv_data *bsp_priv, 290fb98db1SHeiko Stübner int tx_delay, int rx_delay); 300fb98db1SHeiko Stübner void (*set_to_rmii)(struct rk_priv_data *bsp_priv); 310fb98db1SHeiko Stübner void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed); 320fb98db1SHeiko Stübner void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed); 332f2b60a0SDavid Wu void (*set_clock_selection)(struct rk_priv_data *bsp_priv, bool input, 342f2b60a0SDavid Wu bool enable); 35fecd4d7eSDavid Wu void (*integrated_phy_powerup)(struct rk_priv_data *bsp_priv); 360546b224SJohn Keeping bool regs_valid; 373bb3d6b1SDavid Wu u32 regs[]; 380fb98db1SHeiko Stübner }; 390fb98db1SHeiko Stübner 40ea449f7fSSebastian Reichel static const char * const rk_clocks[] = { 41ea449f7fSSebastian Reichel "aclk_mac", "pclk_mac", "mac_clk_tx", "clk_mac_speed", 42ea449f7fSSebastian Reichel }; 43ea449f7fSSebastian Reichel 44ea449f7fSSebastian Reichel static const char * const rk_rmii_clocks[] = { 45ea449f7fSSebastian Reichel "mac_clk_rx", "clk_mac_ref", "clk_mac_refout", 46ea449f7fSSebastian Reichel }; 47ea449f7fSSebastian Reichel 48ea449f7fSSebastian Reichel enum rk_clocks_index { 49ea449f7fSSebastian Reichel RK_ACLK_MAC = 0, 50ea449f7fSSebastian Reichel RK_PCLK_MAC, 51ea449f7fSSebastian Reichel RK_MAC_CLK_TX, 52ea449f7fSSebastian Reichel RK_CLK_MAC_SPEED, 53ea449f7fSSebastian Reichel RK_MAC_CLK_RX, 54ea449f7fSSebastian Reichel RK_CLK_MAC_REF, 55ea449f7fSSebastian Reichel RK_CLK_MAC_REFOUT, 56ea449f7fSSebastian Reichel }; 57ea449f7fSSebastian Reichel 587ad269eaSRoger Chen struct rk_priv_data { 597ad269eaSRoger Chen struct platform_device *pdev; 600c65b2b9SAndrew Lunn phy_interface_t phy_iface; 613bb3d6b1SDavid Wu int id; 622e12f536SRomain Perier struct regulator *regulator; 63229666c1SVincent Palatin bool suspended; 6492c2588fSJoachim Eastwood const struct rk_gmac_ops *ops; 657ad269eaSRoger Chen 667ad269eaSRoger Chen bool clk_enabled; 677ad269eaSRoger Chen bool clock_input; 68fecd4d7eSDavid Wu bool integrated_phy; 697ad269eaSRoger Chen 70ea449f7fSSebastian Reichel struct clk_bulk_data *clks; 71ea449f7fSSebastian Reichel int num_clks; 727ad269eaSRoger Chen struct clk *clk_mac; 73fecd4d7eSDavid Wu struct clk *clk_phy; 74fecd4d7eSDavid Wu 75fecd4d7eSDavid Wu struct reset_control *phy_reset; 767ad269eaSRoger Chen 777ad269eaSRoger Chen int tx_delay; 787ad269eaSRoger Chen int rx_delay; 797ad269eaSRoger Chen 807ad269eaSRoger Chen struct regmap *grf; 812f2b60a0SDavid Wu struct regmap *php_grf; 827ad269eaSRoger Chen }; 837ad269eaSRoger Chen 847ad269eaSRoger Chen #define HIWORD_UPDATE(val, mask, shift) \ 857ad269eaSRoger Chen ((val) << (shift) | (mask) << ((shift) + 16)) 867ad269eaSRoger Chen 877ad269eaSRoger Chen #define GRF_BIT(nr) (BIT(nr) | BIT(nr+16)) 887ad269eaSRoger Chen #define GRF_CLR_BIT(nr) (BIT(nr+16)) 897ad269eaSRoger Chen 90eaf70ad1SWadim Egorov #define DELAY_ENABLE(soc, tx, rx) \ 91eaf70ad1SWadim Egorov (((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \ 92eaf70ad1SWadim Egorov ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE)) 93eaf70ad1SWadim Egorov 9423c94d63SDavid Wu #define PX30_GRF_GMAC_CON1 0x0904 9523c94d63SDavid Wu 9623c94d63SDavid Wu /* PX30_GRF_GMAC_CON1 */ 9723c94d63SDavid Wu #define PX30_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \ 9823c94d63SDavid Wu GRF_BIT(6)) 9923c94d63SDavid Wu #define PX30_GMAC_SPEED_10M GRF_CLR_BIT(2) 10023c94d63SDavid Wu #define PX30_GMAC_SPEED_100M GRF_BIT(2) 10123c94d63SDavid Wu 10223c94d63SDavid Wu static void px30_set_to_rmii(struct rk_priv_data *bsp_priv) 10323c94d63SDavid Wu { 10423c94d63SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 10523c94d63SDavid Wu 10623c94d63SDavid Wu if (IS_ERR(bsp_priv->grf)) { 10723c94d63SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 10823c94d63SDavid Wu return; 10923c94d63SDavid Wu } 11023c94d63SDavid Wu 11123c94d63SDavid Wu regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1, 11223c94d63SDavid Wu PX30_GMAC_PHY_INTF_SEL_RMII); 11323c94d63SDavid Wu } 11423c94d63SDavid Wu 11523c94d63SDavid Wu static void px30_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 11623c94d63SDavid Wu { 117ea449f7fSSebastian Reichel struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk; 11823c94d63SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 11923c94d63SDavid Wu int ret; 12023c94d63SDavid Wu 121ea449f7fSSebastian Reichel if (!clk_mac_speed) { 12223c94d63SDavid Wu dev_err(dev, "%s: Missing clk_mac_speed clock\n", __func__); 12323c94d63SDavid Wu return; 12423c94d63SDavid Wu } 12523c94d63SDavid Wu 12623c94d63SDavid Wu if (speed == 10) { 12723c94d63SDavid Wu regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1, 12823c94d63SDavid Wu PX30_GMAC_SPEED_10M); 12923c94d63SDavid Wu 130ea449f7fSSebastian Reichel ret = clk_set_rate(clk_mac_speed, 2500000); 13123c94d63SDavid Wu if (ret) 13223c94d63SDavid Wu dev_err(dev, "%s: set clk_mac_speed rate 2500000 failed: %d\n", 13323c94d63SDavid Wu __func__, ret); 13423c94d63SDavid Wu } else if (speed == 100) { 13523c94d63SDavid Wu regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1, 13623c94d63SDavid Wu PX30_GMAC_SPEED_100M); 13723c94d63SDavid Wu 138ea449f7fSSebastian Reichel ret = clk_set_rate(clk_mac_speed, 25000000); 13923c94d63SDavid Wu if (ret) 14023c94d63SDavid Wu dev_err(dev, "%s: set clk_mac_speed rate 25000000 failed: %d\n", 14123c94d63SDavid Wu __func__, ret); 14223c94d63SDavid Wu 14323c94d63SDavid Wu } else { 14423c94d63SDavid Wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 14523c94d63SDavid Wu } 14623c94d63SDavid Wu } 14723c94d63SDavid Wu 14823c94d63SDavid Wu static const struct rk_gmac_ops px30_ops = { 14923c94d63SDavid Wu .set_to_rmii = px30_set_to_rmii, 15023c94d63SDavid Wu .set_rmii_speed = px30_set_rmii_speed, 15123c94d63SDavid Wu }; 15223c94d63SDavid Wu 15305946876SDavid Wu #define RK3128_GRF_MAC_CON0 0x0168 15405946876SDavid Wu #define RK3128_GRF_MAC_CON1 0x016c 15505946876SDavid Wu 15605946876SDavid Wu /* RK3128_GRF_MAC_CON0 */ 15705946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_ENABLE GRF_BIT(14) 15805946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14) 15905946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 16005946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 16105946876SDavid Wu #define RK3128_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 16205946876SDavid Wu #define RK3128_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 16305946876SDavid Wu 16405946876SDavid Wu /* RK3128_GRF_MAC_CON1 */ 16505946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RGMII \ 16605946876SDavid Wu (GRF_BIT(6) | GRF_CLR_BIT(7) | GRF_CLR_BIT(8)) 16705946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RMII \ 16805946876SDavid Wu (GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | GRF_BIT(8)) 16905946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL GRF_BIT(9) 17005946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(9) 17105946876SDavid Wu #define RK3128_GMAC_SPEED_10M GRF_CLR_BIT(10) 17205946876SDavid Wu #define RK3128_GMAC_SPEED_100M GRF_BIT(10) 17305946876SDavid Wu #define RK3128_GMAC_RMII_CLK_25M GRF_BIT(11) 17405946876SDavid Wu #define RK3128_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(11) 17505946876SDavid Wu #define RK3128_GMAC_CLK_125M (GRF_CLR_BIT(12) | GRF_CLR_BIT(13)) 17605946876SDavid Wu #define RK3128_GMAC_CLK_25M (GRF_BIT(12) | GRF_BIT(13)) 17705946876SDavid Wu #define RK3128_GMAC_CLK_2_5M (GRF_CLR_BIT(12) | GRF_BIT(13)) 17805946876SDavid Wu #define RK3128_GMAC_RMII_MODE GRF_BIT(14) 17905946876SDavid Wu #define RK3128_GMAC_RMII_MODE_CLR GRF_CLR_BIT(14) 18005946876SDavid Wu 18105946876SDavid Wu static void rk3128_set_to_rgmii(struct rk_priv_data *bsp_priv, 18205946876SDavid Wu int tx_delay, int rx_delay) 18305946876SDavid Wu { 18405946876SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 18505946876SDavid Wu 18605946876SDavid Wu if (IS_ERR(bsp_priv->grf)) { 18705946876SDavid Wu dev_err(dev, "Missing rockchip,grf property\n"); 18805946876SDavid Wu return; 18905946876SDavid Wu } 19005946876SDavid Wu 19105946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 19205946876SDavid Wu RK3128_GMAC_PHY_INTF_SEL_RGMII | 19305946876SDavid Wu RK3128_GMAC_RMII_MODE_CLR); 19405946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON0, 19505946876SDavid Wu DELAY_ENABLE(RK3128, tx_delay, rx_delay) | 19605946876SDavid Wu RK3128_GMAC_CLK_RX_DL_CFG(rx_delay) | 19705946876SDavid Wu RK3128_GMAC_CLK_TX_DL_CFG(tx_delay)); 19805946876SDavid Wu } 19905946876SDavid Wu 20005946876SDavid Wu static void rk3128_set_to_rmii(struct rk_priv_data *bsp_priv) 20105946876SDavid Wu { 20205946876SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 20305946876SDavid Wu 20405946876SDavid Wu if (IS_ERR(bsp_priv->grf)) { 20505946876SDavid Wu dev_err(dev, "Missing rockchip,grf property\n"); 20605946876SDavid Wu return; 20705946876SDavid Wu } 20805946876SDavid Wu 20905946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 21005946876SDavid Wu RK3128_GMAC_PHY_INTF_SEL_RMII | RK3128_GMAC_RMII_MODE); 21105946876SDavid Wu } 21205946876SDavid Wu 21305946876SDavid Wu static void rk3128_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 21405946876SDavid Wu { 21505946876SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 21605946876SDavid Wu 21705946876SDavid Wu if (IS_ERR(bsp_priv->grf)) { 21805946876SDavid Wu dev_err(dev, "Missing rockchip,grf property\n"); 21905946876SDavid Wu return; 22005946876SDavid Wu } 22105946876SDavid Wu 22205946876SDavid Wu if (speed == 10) 22305946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 22405946876SDavid Wu RK3128_GMAC_CLK_2_5M); 22505946876SDavid Wu else if (speed == 100) 22605946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 22705946876SDavid Wu RK3128_GMAC_CLK_25M); 22805946876SDavid Wu else if (speed == 1000) 22905946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 23005946876SDavid Wu RK3128_GMAC_CLK_125M); 23105946876SDavid Wu else 23205946876SDavid Wu dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 23305946876SDavid Wu } 23405946876SDavid Wu 23505946876SDavid Wu static void rk3128_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 23605946876SDavid Wu { 23705946876SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 23805946876SDavid Wu 23905946876SDavid Wu if (IS_ERR(bsp_priv->grf)) { 24005946876SDavid Wu dev_err(dev, "Missing rockchip,grf property\n"); 24105946876SDavid Wu return; 24205946876SDavid Wu } 24305946876SDavid Wu 24405946876SDavid Wu if (speed == 10) { 24505946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 24605946876SDavid Wu RK3128_GMAC_RMII_CLK_2_5M | 24705946876SDavid Wu RK3128_GMAC_SPEED_10M); 24805946876SDavid Wu } else if (speed == 100) { 24905946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, 25005946876SDavid Wu RK3128_GMAC_RMII_CLK_25M | 25105946876SDavid Wu RK3128_GMAC_SPEED_100M); 25205946876SDavid Wu } else { 25305946876SDavid Wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 25405946876SDavid Wu } 25505946876SDavid Wu } 25605946876SDavid Wu 25705946876SDavid Wu static const struct rk_gmac_ops rk3128_ops = { 25805946876SDavid Wu .set_to_rgmii = rk3128_set_to_rgmii, 25905946876SDavid Wu .set_to_rmii = rk3128_set_to_rmii, 26005946876SDavid Wu .set_rgmii_speed = rk3128_set_rgmii_speed, 26105946876SDavid Wu .set_rmii_speed = rk3128_set_rmii_speed, 26205946876SDavid Wu }; 26305946876SDavid Wu 264e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON0 0x0900 265e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON1 0x0904 266e7ffd812SXing Zheng 2676fa12c78SDavid Wu #define RK3228_GRF_CON_MUX 0x50 2686fa12c78SDavid Wu 269e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON0 */ 270e7ffd812SXing Zheng #define RK3228_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 271e7ffd812SXing Zheng #define RK3228_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 272e7ffd812SXing Zheng 273e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON1 */ 274e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RGMII \ 275e7ffd812SXing Zheng (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6)) 276e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RMII \ 277e7ffd812SXing Zheng (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6)) 278e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL GRF_BIT(3) 279e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 280e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_10M GRF_CLR_BIT(2) 281e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_100M GRF_BIT(2) 282e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_25M GRF_BIT(7) 283e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7) 284e7ffd812SXing Zheng #define RK3228_GMAC_CLK_125M (GRF_CLR_BIT(8) | GRF_CLR_BIT(9)) 285e7ffd812SXing Zheng #define RK3228_GMAC_CLK_25M (GRF_BIT(8) | GRF_BIT(9)) 286e7ffd812SXing Zheng #define RK3228_GMAC_CLK_2_5M (GRF_CLR_BIT(8) | GRF_BIT(9)) 287e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE GRF_BIT(10) 288e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE_CLR GRF_CLR_BIT(10) 289e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0) 290e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0) 291e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1) 292e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(1) 293e7ffd812SXing Zheng 2946fa12c78SDavid Wu /* RK3228_GRF_COM_MUX */ 2956fa12c78SDavid Wu #define RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY GRF_BIT(15) 2966fa12c78SDavid Wu 297e7ffd812SXing Zheng static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv, 298e7ffd812SXing Zheng int tx_delay, int rx_delay) 299e7ffd812SXing Zheng { 300e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 301e7ffd812SXing Zheng 302e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 303e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 304e7ffd812SXing Zheng return; 305e7ffd812SXing Zheng } 306e7ffd812SXing Zheng 307e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 308e7ffd812SXing Zheng RK3228_GMAC_PHY_INTF_SEL_RGMII | 309e7ffd812SXing Zheng RK3228_GMAC_RMII_MODE_CLR | 310eaf70ad1SWadim Egorov DELAY_ENABLE(RK3228, tx_delay, rx_delay)); 311e7ffd812SXing Zheng 312e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON0, 313e7ffd812SXing Zheng RK3228_GMAC_CLK_RX_DL_CFG(rx_delay) | 314e7ffd812SXing Zheng RK3228_GMAC_CLK_TX_DL_CFG(tx_delay)); 315e7ffd812SXing Zheng } 316e7ffd812SXing Zheng 317e7ffd812SXing Zheng static void rk3228_set_to_rmii(struct rk_priv_data *bsp_priv) 318e7ffd812SXing Zheng { 319e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 320e7ffd812SXing Zheng 321e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 322e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 323e7ffd812SXing Zheng return; 324e7ffd812SXing Zheng } 325e7ffd812SXing Zheng 326e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 327e7ffd812SXing Zheng RK3228_GMAC_PHY_INTF_SEL_RMII | 328e7ffd812SXing Zheng RK3228_GMAC_RMII_MODE); 329e7ffd812SXing Zheng 330e7ffd812SXing Zheng /* set MAC to RMII mode */ 331e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, GRF_BIT(11)); 332e7ffd812SXing Zheng } 333e7ffd812SXing Zheng 334e7ffd812SXing Zheng static void rk3228_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 335e7ffd812SXing Zheng { 336e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 337e7ffd812SXing Zheng 338e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 339e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 340e7ffd812SXing Zheng return; 341e7ffd812SXing Zheng } 342e7ffd812SXing Zheng 343e7ffd812SXing Zheng if (speed == 10) 344e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 345e7ffd812SXing Zheng RK3228_GMAC_CLK_2_5M); 346e7ffd812SXing Zheng else if (speed == 100) 347e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 348e7ffd812SXing Zheng RK3228_GMAC_CLK_25M); 349e7ffd812SXing Zheng else if (speed == 1000) 350e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 351e7ffd812SXing Zheng RK3228_GMAC_CLK_125M); 352e7ffd812SXing Zheng else 353e7ffd812SXing Zheng dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 354e7ffd812SXing Zheng } 355e7ffd812SXing Zheng 356e7ffd812SXing Zheng static void rk3228_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 357e7ffd812SXing Zheng { 358e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev; 359e7ffd812SXing Zheng 360e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) { 361e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n"); 362e7ffd812SXing Zheng return; 363e7ffd812SXing Zheng } 364e7ffd812SXing Zheng 365e7ffd812SXing Zheng if (speed == 10) 366e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 367e7ffd812SXing Zheng RK3228_GMAC_RMII_CLK_2_5M | 368e7ffd812SXing Zheng RK3228_GMAC_SPEED_10M); 369e7ffd812SXing Zheng else if (speed == 100) 370e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, 371e7ffd812SXing Zheng RK3228_GMAC_RMII_CLK_25M | 372e7ffd812SXing Zheng RK3228_GMAC_SPEED_100M); 373e7ffd812SXing Zheng else 374e7ffd812SXing Zheng dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 375e7ffd812SXing Zheng } 376e7ffd812SXing Zheng 3776fa12c78SDavid Wu static void rk3228_integrated_phy_powerup(struct rk_priv_data *priv) 3786fa12c78SDavid Wu { 3796fa12c78SDavid Wu regmap_write(priv->grf, RK3228_GRF_CON_MUX, 3806fa12c78SDavid Wu RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY); 3816fa12c78SDavid Wu } 3826fa12c78SDavid Wu 383e7ffd812SXing Zheng static const struct rk_gmac_ops rk3228_ops = { 384e7ffd812SXing Zheng .set_to_rgmii = rk3228_set_to_rgmii, 385e7ffd812SXing Zheng .set_to_rmii = rk3228_set_to_rmii, 386e7ffd812SXing Zheng .set_rgmii_speed = rk3228_set_rgmii_speed, 387e7ffd812SXing Zheng .set_rmii_speed = rk3228_set_rmii_speed, 3886fa12c78SDavid Wu .integrated_phy_powerup = rk3228_integrated_phy_powerup, 389e7ffd812SXing Zheng }; 390e7ffd812SXing Zheng 3917ad269eaSRoger Chen #define RK3288_GRF_SOC_CON1 0x0248 3927ad269eaSRoger Chen #define RK3288_GRF_SOC_CON3 0x0250 3937ad269eaSRoger Chen 3947ad269eaSRoger Chen /*RK3288_GRF_SOC_CON1*/ 3950fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(6) | GRF_CLR_BIT(7) | \ 3960fb98db1SHeiko Stübner GRF_CLR_BIT(8)) 3970fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | \ 3980fb98db1SHeiko Stübner GRF_BIT(8)) 3990fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL GRF_BIT(9) 4000fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(9) 4010fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_10M GRF_CLR_BIT(10) 4020fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_100M GRF_BIT(10) 4030fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_25M GRF_BIT(11) 4040fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(11) 4050fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_125M (GRF_CLR_BIT(12) | GRF_CLR_BIT(13)) 4060fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_25M (GRF_BIT(12) | GRF_BIT(13)) 4070fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_2_5M (GRF_CLR_BIT(12) | GRF_BIT(13)) 4080fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE GRF_BIT(14) 4090fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE_CLR GRF_CLR_BIT(14) 4107ad269eaSRoger Chen 4117ad269eaSRoger Chen /*RK3288_GRF_SOC_CON3*/ 4120fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_ENABLE GRF_BIT(14) 4130fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14) 4140fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 4150fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 4160fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 4170fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 4187ad269eaSRoger Chen 4190fb98db1SHeiko Stübner static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv, 4207ad269eaSRoger Chen int tx_delay, int rx_delay) 4217ad269eaSRoger Chen { 4227ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 4237ad269eaSRoger Chen 4247ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 425d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 4267ad269eaSRoger Chen return; 4277ad269eaSRoger Chen } 4287ad269eaSRoger Chen 4297ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4300fb98db1SHeiko Stübner RK3288_GMAC_PHY_INTF_SEL_RGMII | 4310fb98db1SHeiko Stübner RK3288_GMAC_RMII_MODE_CLR); 4327ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3, 433eaf70ad1SWadim Egorov DELAY_ENABLE(RK3288, tx_delay, rx_delay) | 4340fb98db1SHeiko Stübner RK3288_GMAC_CLK_RX_DL_CFG(rx_delay) | 4350fb98db1SHeiko Stübner RK3288_GMAC_CLK_TX_DL_CFG(tx_delay)); 4367ad269eaSRoger Chen } 4377ad269eaSRoger Chen 4380fb98db1SHeiko Stübner static void rk3288_set_to_rmii(struct rk_priv_data *bsp_priv) 4397ad269eaSRoger Chen { 4407ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 4417ad269eaSRoger Chen 4427ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 443d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 4447ad269eaSRoger Chen return; 4457ad269eaSRoger Chen } 4467ad269eaSRoger Chen 4477ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4480fb98db1SHeiko Stübner RK3288_GMAC_PHY_INTF_SEL_RMII | RK3288_GMAC_RMII_MODE); 4497ad269eaSRoger Chen } 4507ad269eaSRoger Chen 4510fb98db1SHeiko Stübner static void rk3288_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 4527ad269eaSRoger Chen { 4537ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 4547ad269eaSRoger Chen 4557ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 456d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 4577ad269eaSRoger Chen return; 4587ad269eaSRoger Chen } 4597ad269eaSRoger Chen 4607ad269eaSRoger Chen if (speed == 10) 4610fb98db1SHeiko Stübner regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4620fb98db1SHeiko Stübner RK3288_GMAC_CLK_2_5M); 4637ad269eaSRoger Chen else if (speed == 100) 4640fb98db1SHeiko Stübner regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4650fb98db1SHeiko Stübner RK3288_GMAC_CLK_25M); 4667ad269eaSRoger Chen else if (speed == 1000) 4670fb98db1SHeiko Stübner regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4680fb98db1SHeiko Stübner RK3288_GMAC_CLK_125M); 4697ad269eaSRoger Chen else 4707ad269eaSRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 4717ad269eaSRoger Chen } 4727ad269eaSRoger Chen 4730fb98db1SHeiko Stübner static void rk3288_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 4747ad269eaSRoger Chen { 4757ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 4767ad269eaSRoger Chen 4777ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) { 478d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n"); 4797ad269eaSRoger Chen return; 4807ad269eaSRoger Chen } 4817ad269eaSRoger Chen 4827ad269eaSRoger Chen if (speed == 10) { 4837ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4840fb98db1SHeiko Stübner RK3288_GMAC_RMII_CLK_2_5M | 4850fb98db1SHeiko Stübner RK3288_GMAC_SPEED_10M); 4867ad269eaSRoger Chen } else if (speed == 100) { 4877ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, 4880fb98db1SHeiko Stübner RK3288_GMAC_RMII_CLK_25M | 4890fb98db1SHeiko Stübner RK3288_GMAC_SPEED_100M); 4907ad269eaSRoger Chen } else { 4917ad269eaSRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 4927ad269eaSRoger Chen } 4937ad269eaSRoger Chen } 4947ad269eaSRoger Chen 49592c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3288_ops = { 4960fb98db1SHeiko Stübner .set_to_rgmii = rk3288_set_to_rgmii, 4970fb98db1SHeiko Stübner .set_to_rmii = rk3288_set_to_rmii, 4980fb98db1SHeiko Stübner .set_rgmii_speed = rk3288_set_rgmii_speed, 4990fb98db1SHeiko Stübner .set_rmii_speed = rk3288_set_rmii_speed, 5000fb98db1SHeiko Stübner }; 5010fb98db1SHeiko Stübner 502b4ac9456STobias Schramm #define RK3308_GRF_MAC_CON0 0x04a0 503b4ac9456STobias Schramm 504b4ac9456STobias Schramm /* RK3308_GRF_MAC_CON0 */ 505b4ac9456STobias Schramm #define RK3308_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(2) | GRF_CLR_BIT(3) | \ 506b4ac9456STobias Schramm GRF_BIT(4)) 507b4ac9456STobias Schramm #define RK3308_GMAC_FLOW_CTRL GRF_BIT(3) 508b4ac9456STobias Schramm #define RK3308_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 509b4ac9456STobias Schramm #define RK3308_GMAC_SPEED_10M GRF_CLR_BIT(0) 510b4ac9456STobias Schramm #define RK3308_GMAC_SPEED_100M GRF_BIT(0) 511b4ac9456STobias Schramm 512b4ac9456STobias Schramm static void rk3308_set_to_rmii(struct rk_priv_data *bsp_priv) 513b4ac9456STobias Schramm { 514b4ac9456STobias Schramm struct device *dev = &bsp_priv->pdev->dev; 515b4ac9456STobias Schramm 516b4ac9456STobias Schramm if (IS_ERR(bsp_priv->grf)) { 517b4ac9456STobias Schramm dev_err(dev, "Missing rockchip,grf property\n"); 518b4ac9456STobias Schramm return; 519b4ac9456STobias Schramm } 520b4ac9456STobias Schramm 521b4ac9456STobias Schramm regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0, 522b4ac9456STobias Schramm RK3308_GMAC_PHY_INTF_SEL_RMII); 523b4ac9456STobias Schramm } 524b4ac9456STobias Schramm 525b4ac9456STobias Schramm static void rk3308_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 526b4ac9456STobias Schramm { 527b4ac9456STobias Schramm struct device *dev = &bsp_priv->pdev->dev; 528b4ac9456STobias Schramm 529b4ac9456STobias Schramm if (IS_ERR(bsp_priv->grf)) { 530b4ac9456STobias Schramm dev_err(dev, "Missing rockchip,grf property\n"); 531b4ac9456STobias Schramm return; 532b4ac9456STobias Schramm } 533b4ac9456STobias Schramm 534b4ac9456STobias Schramm if (speed == 10) { 535b4ac9456STobias Schramm regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0, 536b4ac9456STobias Schramm RK3308_GMAC_SPEED_10M); 537b4ac9456STobias Schramm } else if (speed == 100) { 538b4ac9456STobias Schramm regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0, 539b4ac9456STobias Schramm RK3308_GMAC_SPEED_100M); 540b4ac9456STobias Schramm } else { 541b4ac9456STobias Schramm dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 542b4ac9456STobias Schramm } 543b4ac9456STobias Schramm } 544b4ac9456STobias Schramm 545b4ac9456STobias Schramm static const struct rk_gmac_ops rk3308_ops = { 546b4ac9456STobias Schramm .set_to_rmii = rk3308_set_to_rmii, 547b4ac9456STobias Schramm .set_rmii_speed = rk3308_set_rmii_speed, 548b4ac9456STobias Schramm }; 549b4ac9456STobias Schramm 550d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON0 0x0900 551d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON1 0x0904 5528bdf63bdSDavid Wu #define RK3328_GRF_MAC_CON2 0x0908 5538bdf63bdSDavid Wu #define RK3328_GRF_MACPHY_CON1 0xb04 554d4ff816eSdavid.wu 555d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON0 */ 556d4ff816eSdavid.wu #define RK3328_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7) 557d4ff816eSdavid.wu #define RK3328_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 558d4ff816eSdavid.wu 559d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON1 */ 560d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RGMII \ 561d4ff816eSdavid.wu (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6)) 562d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RMII \ 563d4ff816eSdavid.wu (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6)) 564d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL GRF_BIT(3) 565d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 566d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_10M GRF_CLR_BIT(2) 567d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_100M GRF_BIT(2) 568d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_25M GRF_BIT(7) 569d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7) 570d4ff816eSdavid.wu #define RK3328_GMAC_CLK_125M (GRF_CLR_BIT(11) | GRF_CLR_BIT(12)) 571d4ff816eSdavid.wu #define RK3328_GMAC_CLK_25M (GRF_BIT(11) | GRF_BIT(12)) 572d4ff816eSdavid.wu #define RK3328_GMAC_CLK_2_5M (GRF_CLR_BIT(11) | GRF_BIT(12)) 573d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE GRF_BIT(9) 574d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE_CLR GRF_CLR_BIT(9) 575d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0) 576d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0) 577d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1) 578d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(0) 579d4ff816eSdavid.wu 5808bdf63bdSDavid Wu /* RK3328_GRF_MACPHY_CON1 */ 5818bdf63bdSDavid Wu #define RK3328_MACPHY_RMII_MODE GRF_BIT(9) 5828bdf63bdSDavid Wu 583d4ff816eSdavid.wu static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv, 584d4ff816eSdavid.wu int tx_delay, int rx_delay) 585d4ff816eSdavid.wu { 586d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev; 587d4ff816eSdavid.wu 588d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) { 589d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n"); 590d4ff816eSdavid.wu return; 591d4ff816eSdavid.wu } 592d4ff816eSdavid.wu 593d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, 594d4ff816eSdavid.wu RK3328_GMAC_PHY_INTF_SEL_RGMII | 595d4ff816eSdavid.wu RK3328_GMAC_RMII_MODE_CLR | 596d4ff816eSdavid.wu RK3328_GMAC_RXCLK_DLY_ENABLE | 597d4ff816eSdavid.wu RK3328_GMAC_TXCLK_DLY_ENABLE); 598d4ff816eSdavid.wu 599d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON0, 600d4ff816eSdavid.wu RK3328_GMAC_CLK_RX_DL_CFG(rx_delay) | 601d4ff816eSdavid.wu RK3328_GMAC_CLK_TX_DL_CFG(tx_delay)); 602d4ff816eSdavid.wu } 603d4ff816eSdavid.wu 604d4ff816eSdavid.wu static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv) 605d4ff816eSdavid.wu { 606d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev; 6078bdf63bdSDavid Wu unsigned int reg; 608d4ff816eSdavid.wu 609d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) { 610d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n"); 611d4ff816eSdavid.wu return; 612d4ff816eSdavid.wu } 613d4ff816eSdavid.wu 6148bdf63bdSDavid Wu reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 : 6158bdf63bdSDavid Wu RK3328_GRF_MAC_CON1; 6168bdf63bdSDavid Wu 6178bdf63bdSDavid Wu regmap_write(bsp_priv->grf, reg, 618d4ff816eSdavid.wu RK3328_GMAC_PHY_INTF_SEL_RMII | 619d4ff816eSdavid.wu RK3328_GMAC_RMII_MODE); 620d4ff816eSdavid.wu } 621d4ff816eSdavid.wu 622d4ff816eSdavid.wu static void rk3328_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 623d4ff816eSdavid.wu { 624d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev; 625d4ff816eSdavid.wu 626d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) { 627d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n"); 628d4ff816eSdavid.wu return; 629d4ff816eSdavid.wu } 630d4ff816eSdavid.wu 631d4ff816eSdavid.wu if (speed == 10) 632d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, 633d4ff816eSdavid.wu RK3328_GMAC_CLK_2_5M); 634d4ff816eSdavid.wu else if (speed == 100) 635d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, 636d4ff816eSdavid.wu RK3328_GMAC_CLK_25M); 637d4ff816eSdavid.wu else if (speed == 1000) 638d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, 639d4ff816eSdavid.wu RK3328_GMAC_CLK_125M); 640d4ff816eSdavid.wu else 641d4ff816eSdavid.wu dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 642d4ff816eSdavid.wu } 643d4ff816eSdavid.wu 644d4ff816eSdavid.wu static void rk3328_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 645d4ff816eSdavid.wu { 646d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev; 6478bdf63bdSDavid Wu unsigned int reg; 648d4ff816eSdavid.wu 649d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) { 650d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n"); 651d4ff816eSdavid.wu return; 652d4ff816eSdavid.wu } 653d4ff816eSdavid.wu 6548bdf63bdSDavid Wu reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 : 6558bdf63bdSDavid Wu RK3328_GRF_MAC_CON1; 6568bdf63bdSDavid Wu 657d4ff816eSdavid.wu if (speed == 10) 6588bdf63bdSDavid Wu regmap_write(bsp_priv->grf, reg, 659d4ff816eSdavid.wu RK3328_GMAC_RMII_CLK_2_5M | 660d4ff816eSdavid.wu RK3328_GMAC_SPEED_10M); 661d4ff816eSdavid.wu else if (speed == 100) 6628bdf63bdSDavid Wu regmap_write(bsp_priv->grf, reg, 663d4ff816eSdavid.wu RK3328_GMAC_RMII_CLK_25M | 664d4ff816eSdavid.wu RK3328_GMAC_SPEED_100M); 665d4ff816eSdavid.wu else 666d4ff816eSdavid.wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 667d4ff816eSdavid.wu } 668d4ff816eSdavid.wu 6698bdf63bdSDavid Wu static void rk3328_integrated_phy_powerup(struct rk_priv_data *priv) 6708bdf63bdSDavid Wu { 6718bdf63bdSDavid Wu regmap_write(priv->grf, RK3328_GRF_MACPHY_CON1, 6728bdf63bdSDavid Wu RK3328_MACPHY_RMII_MODE); 6738bdf63bdSDavid Wu } 6748bdf63bdSDavid Wu 675d4ff816eSdavid.wu static const struct rk_gmac_ops rk3328_ops = { 676d4ff816eSdavid.wu .set_to_rgmii = rk3328_set_to_rgmii, 677d4ff816eSdavid.wu .set_to_rmii = rk3328_set_to_rmii, 678d4ff816eSdavid.wu .set_rgmii_speed = rk3328_set_rgmii_speed, 679d4ff816eSdavid.wu .set_rmii_speed = rk3328_set_rmii_speed, 6808bdf63bdSDavid Wu .integrated_phy_powerup = rk3328_integrated_phy_powerup, 681d4ff816eSdavid.wu }; 682d4ff816eSdavid.wu 683ba289af8SRoger Chen #define RK3366_GRF_SOC_CON6 0x0418 684ba289af8SRoger Chen #define RK3366_GRF_SOC_CON7 0x041c 685ba289af8SRoger Chen 686ba289af8SRoger Chen /* RK3366_GRF_SOC_CON6 */ 687ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 688ba289af8SRoger Chen GRF_CLR_BIT(11)) 689ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 690ba289af8SRoger Chen GRF_BIT(11)) 691ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL GRF_BIT(8) 692ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 693ba289af8SRoger Chen #define RK3366_GMAC_SPEED_10M GRF_CLR_BIT(7) 694ba289af8SRoger Chen #define RK3366_GMAC_SPEED_100M GRF_BIT(7) 695ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_25M GRF_BIT(3) 696ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 697ba289af8SRoger Chen #define RK3366_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 698ba289af8SRoger Chen #define RK3366_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 699ba289af8SRoger Chen #define RK3366_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 700ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE GRF_BIT(6) 701ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 702ba289af8SRoger Chen 703ba289af8SRoger Chen /* RK3366_GRF_SOC_CON7 */ 704ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 705ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 706ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 707ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 708ba289af8SRoger Chen #define RK3366_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 709ba289af8SRoger Chen #define RK3366_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 710ba289af8SRoger Chen 711ba289af8SRoger Chen static void rk3366_set_to_rgmii(struct rk_priv_data *bsp_priv, 712ba289af8SRoger Chen int tx_delay, int rx_delay) 713ba289af8SRoger Chen { 714ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 715ba289af8SRoger Chen 716ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 717ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 718ba289af8SRoger Chen return; 719ba289af8SRoger Chen } 720ba289af8SRoger Chen 721ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 722ba289af8SRoger Chen RK3366_GMAC_PHY_INTF_SEL_RGMII | 723ba289af8SRoger Chen RK3366_GMAC_RMII_MODE_CLR); 724ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON7, 725eaf70ad1SWadim Egorov DELAY_ENABLE(RK3366, tx_delay, rx_delay) | 726ba289af8SRoger Chen RK3366_GMAC_CLK_RX_DL_CFG(rx_delay) | 727ba289af8SRoger Chen RK3366_GMAC_CLK_TX_DL_CFG(tx_delay)); 728ba289af8SRoger Chen } 729ba289af8SRoger Chen 730ba289af8SRoger Chen static void rk3366_set_to_rmii(struct rk_priv_data *bsp_priv) 731ba289af8SRoger Chen { 732ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 733ba289af8SRoger Chen 734ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 735ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 736ba289af8SRoger Chen return; 737ba289af8SRoger Chen } 738ba289af8SRoger Chen 739ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 740ba289af8SRoger Chen RK3366_GMAC_PHY_INTF_SEL_RMII | RK3366_GMAC_RMII_MODE); 741ba289af8SRoger Chen } 742ba289af8SRoger Chen 743ba289af8SRoger Chen static void rk3366_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 744ba289af8SRoger Chen { 745ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 746ba289af8SRoger Chen 747ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 748ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 749ba289af8SRoger Chen return; 750ba289af8SRoger Chen } 751ba289af8SRoger Chen 752ba289af8SRoger Chen if (speed == 10) 753ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 754ba289af8SRoger Chen RK3366_GMAC_CLK_2_5M); 755ba289af8SRoger Chen else if (speed == 100) 756ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 757ba289af8SRoger Chen RK3366_GMAC_CLK_25M); 758ba289af8SRoger Chen else if (speed == 1000) 759ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 760ba289af8SRoger Chen RK3366_GMAC_CLK_125M); 761ba289af8SRoger Chen else 762ba289af8SRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 763ba289af8SRoger Chen } 764ba289af8SRoger Chen 765ba289af8SRoger Chen static void rk3366_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 766ba289af8SRoger Chen { 767ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 768ba289af8SRoger Chen 769ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 770ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 771ba289af8SRoger Chen return; 772ba289af8SRoger Chen } 773ba289af8SRoger Chen 774ba289af8SRoger Chen if (speed == 10) { 775ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 776ba289af8SRoger Chen RK3366_GMAC_RMII_CLK_2_5M | 777ba289af8SRoger Chen RK3366_GMAC_SPEED_10M); 778ba289af8SRoger Chen } else if (speed == 100) { 779ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, 780ba289af8SRoger Chen RK3366_GMAC_RMII_CLK_25M | 781ba289af8SRoger Chen RK3366_GMAC_SPEED_100M); 782ba289af8SRoger Chen } else { 783ba289af8SRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 784ba289af8SRoger Chen } 785ba289af8SRoger Chen } 786ba289af8SRoger Chen 787ba289af8SRoger Chen static const struct rk_gmac_ops rk3366_ops = { 788ba289af8SRoger Chen .set_to_rgmii = rk3366_set_to_rgmii, 789ba289af8SRoger Chen .set_to_rmii = rk3366_set_to_rmii, 790ba289af8SRoger Chen .set_rgmii_speed = rk3366_set_rgmii_speed, 791ba289af8SRoger Chen .set_rmii_speed = rk3366_set_rmii_speed, 792ba289af8SRoger Chen }; 793ba289af8SRoger Chen 794df558854SHeiko Stübner #define RK3368_GRF_SOC_CON15 0x043c 795df558854SHeiko Stübner #define RK3368_GRF_SOC_CON16 0x0440 796df558854SHeiko Stübner 797df558854SHeiko Stübner /* RK3368_GRF_SOC_CON15 */ 798df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 799df558854SHeiko Stübner GRF_CLR_BIT(11)) 800df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 801df558854SHeiko Stübner GRF_BIT(11)) 802df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL GRF_BIT(8) 803df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 804df558854SHeiko Stübner #define RK3368_GMAC_SPEED_10M GRF_CLR_BIT(7) 805df558854SHeiko Stübner #define RK3368_GMAC_SPEED_100M GRF_BIT(7) 806df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_25M GRF_BIT(3) 807df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 808df558854SHeiko Stübner #define RK3368_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 809df558854SHeiko Stübner #define RK3368_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 810df558854SHeiko Stübner #define RK3368_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 811df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE GRF_BIT(6) 812df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 813df558854SHeiko Stübner 814df558854SHeiko Stübner /* RK3368_GRF_SOC_CON16 */ 815df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 816df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 817df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 818df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 819df558854SHeiko Stübner #define RK3368_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 820df558854SHeiko Stübner #define RK3368_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 821df558854SHeiko Stübner 822df558854SHeiko Stübner static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv, 823df558854SHeiko Stübner int tx_delay, int rx_delay) 824df558854SHeiko Stübner { 825df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 826df558854SHeiko Stübner 827df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 828df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 829df558854SHeiko Stübner return; 830df558854SHeiko Stübner } 831df558854SHeiko Stübner 832df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 833df558854SHeiko Stübner RK3368_GMAC_PHY_INTF_SEL_RGMII | 834df558854SHeiko Stübner RK3368_GMAC_RMII_MODE_CLR); 835df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16, 836eaf70ad1SWadim Egorov DELAY_ENABLE(RK3368, tx_delay, rx_delay) | 837df558854SHeiko Stübner RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) | 838df558854SHeiko Stübner RK3368_GMAC_CLK_TX_DL_CFG(tx_delay)); 839df558854SHeiko Stübner } 840df558854SHeiko Stübner 841df558854SHeiko Stübner static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv) 842df558854SHeiko Stübner { 843df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 844df558854SHeiko Stübner 845df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 846df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 847df558854SHeiko Stübner return; 848df558854SHeiko Stübner } 849df558854SHeiko Stübner 850df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 851df558854SHeiko Stübner RK3368_GMAC_PHY_INTF_SEL_RMII | RK3368_GMAC_RMII_MODE); 852df558854SHeiko Stübner } 853df558854SHeiko Stübner 854df558854SHeiko Stübner static void rk3368_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 855df558854SHeiko Stübner { 856df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 857df558854SHeiko Stübner 858df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 859df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 860df558854SHeiko Stübner return; 861df558854SHeiko Stübner } 862df558854SHeiko Stübner 863df558854SHeiko Stübner if (speed == 10) 864df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 865df558854SHeiko Stübner RK3368_GMAC_CLK_2_5M); 866df558854SHeiko Stübner else if (speed == 100) 867df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 868df558854SHeiko Stübner RK3368_GMAC_CLK_25M); 869df558854SHeiko Stübner else if (speed == 1000) 870df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 871df558854SHeiko Stübner RK3368_GMAC_CLK_125M); 872df558854SHeiko Stübner else 873df558854SHeiko Stübner dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 874df558854SHeiko Stübner } 875df558854SHeiko Stübner 876df558854SHeiko Stübner static void rk3368_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 877df558854SHeiko Stübner { 878df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev; 879df558854SHeiko Stübner 880df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) { 881df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 882df558854SHeiko Stübner return; 883df558854SHeiko Stübner } 884df558854SHeiko Stübner 885df558854SHeiko Stübner if (speed == 10) { 886df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 887df558854SHeiko Stübner RK3368_GMAC_RMII_CLK_2_5M | 888df558854SHeiko Stübner RK3368_GMAC_SPEED_10M); 889df558854SHeiko Stübner } else if (speed == 100) { 890df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, 891df558854SHeiko Stübner RK3368_GMAC_RMII_CLK_25M | 892df558854SHeiko Stübner RK3368_GMAC_SPEED_100M); 893df558854SHeiko Stübner } else { 894df558854SHeiko Stübner dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 895df558854SHeiko Stübner } 896df558854SHeiko Stübner } 897df558854SHeiko Stübner 89892c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3368_ops = { 899df558854SHeiko Stübner .set_to_rgmii = rk3368_set_to_rgmii, 900df558854SHeiko Stübner .set_to_rmii = rk3368_set_to_rmii, 901df558854SHeiko Stübner .set_rgmii_speed = rk3368_set_rgmii_speed, 902df558854SHeiko Stübner .set_rmii_speed = rk3368_set_rmii_speed, 903df558854SHeiko Stübner }; 904df558854SHeiko Stübner 905ba289af8SRoger Chen #define RK3399_GRF_SOC_CON5 0xc214 906ba289af8SRoger Chen #define RK3399_GRF_SOC_CON6 0xc218 907ba289af8SRoger Chen 908ba289af8SRoger Chen /* RK3399_GRF_SOC_CON5 */ 909ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \ 910ba289af8SRoger Chen GRF_CLR_BIT(11)) 911ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \ 912ba289af8SRoger Chen GRF_BIT(11)) 913ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL GRF_BIT(8) 914ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8) 915ba289af8SRoger Chen #define RK3399_GMAC_SPEED_10M GRF_CLR_BIT(7) 916ba289af8SRoger Chen #define RK3399_GMAC_SPEED_100M GRF_BIT(7) 917ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_25M GRF_BIT(3) 918ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3) 919ba289af8SRoger Chen #define RK3399_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5)) 920ba289af8SRoger Chen #define RK3399_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5)) 921ba289af8SRoger Chen #define RK3399_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5)) 922ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE GRF_BIT(6) 923ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6) 924ba289af8SRoger Chen 925ba289af8SRoger Chen /* RK3399_GRF_SOC_CON6 */ 926ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) 927ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) 928ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) 929ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) 930ba289af8SRoger Chen #define RK3399_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 931ba289af8SRoger Chen #define RK3399_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 932ba289af8SRoger Chen 933ba289af8SRoger Chen static void rk3399_set_to_rgmii(struct rk_priv_data *bsp_priv, 934ba289af8SRoger Chen int tx_delay, int rx_delay) 935ba289af8SRoger Chen { 936ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 937ba289af8SRoger Chen 938ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 939ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 940ba289af8SRoger Chen return; 941ba289af8SRoger Chen } 942ba289af8SRoger Chen 943ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 944ba289af8SRoger Chen RK3399_GMAC_PHY_INTF_SEL_RGMII | 945ba289af8SRoger Chen RK3399_GMAC_RMII_MODE_CLR); 946ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON6, 947eaf70ad1SWadim Egorov DELAY_ENABLE(RK3399, tx_delay, rx_delay) | 948ba289af8SRoger Chen RK3399_GMAC_CLK_RX_DL_CFG(rx_delay) | 949ba289af8SRoger Chen RK3399_GMAC_CLK_TX_DL_CFG(tx_delay)); 950ba289af8SRoger Chen } 951ba289af8SRoger Chen 952ba289af8SRoger Chen static void rk3399_set_to_rmii(struct rk_priv_data *bsp_priv) 953ba289af8SRoger Chen { 954ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 955ba289af8SRoger Chen 956ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 957ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 958ba289af8SRoger Chen return; 959ba289af8SRoger Chen } 960ba289af8SRoger Chen 961ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 962ba289af8SRoger Chen RK3399_GMAC_PHY_INTF_SEL_RMII | RK3399_GMAC_RMII_MODE); 963ba289af8SRoger Chen } 964ba289af8SRoger Chen 965ba289af8SRoger Chen static void rk3399_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 966ba289af8SRoger Chen { 967ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 968ba289af8SRoger Chen 969ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 970ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 971ba289af8SRoger Chen return; 972ba289af8SRoger Chen } 973ba289af8SRoger Chen 974ba289af8SRoger Chen if (speed == 10) 975ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 976ba289af8SRoger Chen RK3399_GMAC_CLK_2_5M); 977ba289af8SRoger Chen else if (speed == 100) 978ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 979ba289af8SRoger Chen RK3399_GMAC_CLK_25M); 980ba289af8SRoger Chen else if (speed == 1000) 981ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 982ba289af8SRoger Chen RK3399_GMAC_CLK_125M); 983ba289af8SRoger Chen else 984ba289af8SRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); 985ba289af8SRoger Chen } 986ba289af8SRoger Chen 987ba289af8SRoger Chen static void rk3399_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 988ba289af8SRoger Chen { 989ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 990ba289af8SRoger Chen 991ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) { 992ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 993ba289af8SRoger Chen return; 994ba289af8SRoger Chen } 995ba289af8SRoger Chen 996ba289af8SRoger Chen if (speed == 10) { 997ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 998ba289af8SRoger Chen RK3399_GMAC_RMII_CLK_2_5M | 999ba289af8SRoger Chen RK3399_GMAC_SPEED_10M); 1000ba289af8SRoger Chen } else if (speed == 100) { 1001ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, 1002ba289af8SRoger Chen RK3399_GMAC_RMII_CLK_25M | 1003ba289af8SRoger Chen RK3399_GMAC_SPEED_100M); 1004ba289af8SRoger Chen } else { 1005ba289af8SRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 1006ba289af8SRoger Chen } 1007ba289af8SRoger Chen } 1008ba289af8SRoger Chen 1009ba289af8SRoger Chen static const struct rk_gmac_ops rk3399_ops = { 1010ba289af8SRoger Chen .set_to_rgmii = rk3399_set_to_rgmii, 1011ba289af8SRoger Chen .set_to_rmii = rk3399_set_to_rmii, 1012ba289af8SRoger Chen .set_rgmii_speed = rk3399_set_rgmii_speed, 1013ba289af8SRoger Chen .set_rmii_speed = rk3399_set_rmii_speed, 1014ba289af8SRoger Chen }; 1015ba289af8SRoger Chen 10163bb3d6b1SDavid Wu #define RK3568_GRF_GMAC0_CON0 0x0380 10173bb3d6b1SDavid Wu #define RK3568_GRF_GMAC0_CON1 0x0384 10183bb3d6b1SDavid Wu #define RK3568_GRF_GMAC1_CON0 0x0388 10193bb3d6b1SDavid Wu #define RK3568_GRF_GMAC1_CON1 0x038c 10203bb3d6b1SDavid Wu 10213bb3d6b1SDavid Wu /* RK3568_GRF_GMAC0_CON1 && RK3568_GRF_GMAC1_CON1 */ 10223bb3d6b1SDavid Wu #define RK3568_GMAC_PHY_INTF_SEL_RGMII \ 10233bb3d6b1SDavid Wu (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6)) 10243bb3d6b1SDavid Wu #define RK3568_GMAC_PHY_INTF_SEL_RMII \ 10253bb3d6b1SDavid Wu (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6)) 10263bb3d6b1SDavid Wu #define RK3568_GMAC_FLOW_CTRL GRF_BIT(3) 10273bb3d6b1SDavid Wu #define RK3568_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 10283bb3d6b1SDavid Wu #define RK3568_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1) 10293bb3d6b1SDavid Wu #define RK3568_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(1) 10303bb3d6b1SDavid Wu #define RK3568_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0) 10313bb3d6b1SDavid Wu #define RK3568_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0) 10323bb3d6b1SDavid Wu 10333bb3d6b1SDavid Wu /* RK3568_GRF_GMAC0_CON0 && RK3568_GRF_GMAC1_CON0 */ 10343bb3d6b1SDavid Wu #define RK3568_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 10353bb3d6b1SDavid Wu #define RK3568_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 10363bb3d6b1SDavid Wu 10373bb3d6b1SDavid Wu static void rk3568_set_to_rgmii(struct rk_priv_data *bsp_priv, 10383bb3d6b1SDavid Wu int tx_delay, int rx_delay) 10393bb3d6b1SDavid Wu { 10403bb3d6b1SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 10413bb3d6b1SDavid Wu u32 con0, con1; 10423bb3d6b1SDavid Wu 10433bb3d6b1SDavid Wu if (IS_ERR(bsp_priv->grf)) { 10443bb3d6b1SDavid Wu dev_err(dev, "Missing rockchip,grf property\n"); 10453bb3d6b1SDavid Wu return; 10463bb3d6b1SDavid Wu } 10473bb3d6b1SDavid Wu 10483bb3d6b1SDavid Wu con0 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON0 : 10493bb3d6b1SDavid Wu RK3568_GRF_GMAC0_CON0; 10503bb3d6b1SDavid Wu con1 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON1 : 10513bb3d6b1SDavid Wu RK3568_GRF_GMAC0_CON1; 10523bb3d6b1SDavid Wu 10533bb3d6b1SDavid Wu regmap_write(bsp_priv->grf, con0, 10543bb3d6b1SDavid Wu RK3568_GMAC_CLK_RX_DL_CFG(rx_delay) | 10553bb3d6b1SDavid Wu RK3568_GMAC_CLK_TX_DL_CFG(tx_delay)); 10563bb3d6b1SDavid Wu 10573bb3d6b1SDavid Wu regmap_write(bsp_priv->grf, con1, 10583bb3d6b1SDavid Wu RK3568_GMAC_PHY_INTF_SEL_RGMII | 10593bb3d6b1SDavid Wu RK3568_GMAC_RXCLK_DLY_ENABLE | 10603bb3d6b1SDavid Wu RK3568_GMAC_TXCLK_DLY_ENABLE); 10613bb3d6b1SDavid Wu } 10623bb3d6b1SDavid Wu 10633bb3d6b1SDavid Wu static void rk3568_set_to_rmii(struct rk_priv_data *bsp_priv) 10643bb3d6b1SDavid Wu { 10653bb3d6b1SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 10663bb3d6b1SDavid Wu u32 con1; 10673bb3d6b1SDavid Wu 10683bb3d6b1SDavid Wu if (IS_ERR(bsp_priv->grf)) { 10693bb3d6b1SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 10703bb3d6b1SDavid Wu return; 10713bb3d6b1SDavid Wu } 10723bb3d6b1SDavid Wu 10733bb3d6b1SDavid Wu con1 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON1 : 10743bb3d6b1SDavid Wu RK3568_GRF_GMAC0_CON1; 10753bb3d6b1SDavid Wu regmap_write(bsp_priv->grf, con1, RK3568_GMAC_PHY_INTF_SEL_RMII); 10763bb3d6b1SDavid Wu } 10773bb3d6b1SDavid Wu 10783bb3d6b1SDavid Wu static void rk3568_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed) 10793bb3d6b1SDavid Wu { 1080ea449f7fSSebastian Reichel struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk; 10813bb3d6b1SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 10823bb3d6b1SDavid Wu unsigned long rate; 10833bb3d6b1SDavid Wu int ret; 10843bb3d6b1SDavid Wu 10853bb3d6b1SDavid Wu switch (speed) { 10863bb3d6b1SDavid Wu case 10: 10873bb3d6b1SDavid Wu rate = 2500000; 10883bb3d6b1SDavid Wu break; 10893bb3d6b1SDavid Wu case 100: 10903bb3d6b1SDavid Wu rate = 25000000; 10913bb3d6b1SDavid Wu break; 10923bb3d6b1SDavid Wu case 1000: 10933bb3d6b1SDavid Wu rate = 125000000; 10943bb3d6b1SDavid Wu break; 10953bb3d6b1SDavid Wu default: 10963bb3d6b1SDavid Wu dev_err(dev, "unknown speed value for GMAC speed=%d", speed); 10973bb3d6b1SDavid Wu return; 10983bb3d6b1SDavid Wu } 10993bb3d6b1SDavid Wu 1100ea449f7fSSebastian Reichel ret = clk_set_rate(clk_mac_speed, rate); 11013bb3d6b1SDavid Wu if (ret) 11023bb3d6b1SDavid Wu dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n", 11033bb3d6b1SDavid Wu __func__, rate, ret); 11043bb3d6b1SDavid Wu } 11053bb3d6b1SDavid Wu 11063bb3d6b1SDavid Wu static const struct rk_gmac_ops rk3568_ops = { 11073bb3d6b1SDavid Wu .set_to_rgmii = rk3568_set_to_rgmii, 11083bb3d6b1SDavid Wu .set_to_rmii = rk3568_set_to_rmii, 11093bb3d6b1SDavid Wu .set_rgmii_speed = rk3568_set_gmac_speed, 11103bb3d6b1SDavid Wu .set_rmii_speed = rk3568_set_gmac_speed, 11110546b224SJohn Keeping .regs_valid = true, 11123bb3d6b1SDavid Wu .regs = { 11133bb3d6b1SDavid Wu 0xfe2a0000, /* gmac0 */ 11143bb3d6b1SDavid Wu 0xfe010000, /* gmac1 */ 11153bb3d6b1SDavid Wu 0x0, /* sentinel */ 11163bb3d6b1SDavid Wu }, 11173bb3d6b1SDavid Wu }; 11183bb3d6b1SDavid Wu 11192f2b60a0SDavid Wu /* sys_grf */ 11202f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON7 0X031c 11212f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON8 0X0320 11222f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON9 0X0324 11232f2b60a0SDavid Wu 11242f2b60a0SDavid Wu #define RK3588_GMAC_RXCLK_DLY_ENABLE(id) GRF_BIT(2 * (id) + 3) 11252f2b60a0SDavid Wu #define RK3588_GMAC_RXCLK_DLY_DISABLE(id) GRF_CLR_BIT(2 * (id) + 3) 11262f2b60a0SDavid Wu #define RK3588_GMAC_TXCLK_DLY_ENABLE(id) GRF_BIT(2 * (id) + 2) 11272f2b60a0SDavid Wu #define RK3588_GMAC_TXCLK_DLY_DISABLE(id) GRF_CLR_BIT(2 * (id) + 2) 11282f2b60a0SDavid Wu 11292f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0xFF, 8) 11302f2b60a0SDavid Wu #define RK3588_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0xFF, 0) 11312f2b60a0SDavid Wu 11322f2b60a0SDavid Wu /* php_grf */ 11332f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON0 0X0008 11342f2b60a0SDavid Wu #define RK3588_GRF_CLK_CON1 0X0070 11352f2b60a0SDavid Wu 11362f2b60a0SDavid Wu #define RK3588_GMAC_PHY_INTF_SEL_RGMII(id) \ 11372f2b60a0SDavid Wu (GRF_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_CLR_BIT(5 + (id) * 6)) 11382f2b60a0SDavid Wu #define RK3588_GMAC_PHY_INTF_SEL_RMII(id) \ 11392f2b60a0SDavid Wu (GRF_CLR_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_BIT(5 + (id) * 6)) 11402f2b60a0SDavid Wu 11412f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RMII_MODE(id) GRF_BIT(5 * (id)) 11422f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_MODE(id) GRF_CLR_BIT(5 * (id)) 11432f2b60a0SDavid Wu 1144*78a60497SDetlev Casanova #define RK3588_GMAC_CLK_SELECT_CRU(id) GRF_BIT(5 * (id) + 4) 1145*78a60497SDetlev Casanova #define RK3588_GMAC_CLK_SELECT_IO(id) GRF_CLR_BIT(5 * (id) + 4) 11462f2b60a0SDavid Wu 11472f2b60a0SDavid Wu #define RK3588_GMA_CLK_RMII_DIV2(id) GRF_BIT(5 * (id) + 2) 11482f2b60a0SDavid Wu #define RK3588_GMA_CLK_RMII_DIV20(id) GRF_CLR_BIT(5 * (id) + 2) 11492f2b60a0SDavid Wu 11502f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_DIV1(id) \ 11512f2b60a0SDavid Wu (GRF_CLR_BIT(5 * (id) + 2) | GRF_CLR_BIT(5 * (id) + 3)) 11522f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_DIV5(id) \ 11532f2b60a0SDavid Wu (GRF_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3)) 11542f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_DIV50(id) \ 11552f2b60a0SDavid Wu (GRF_CLR_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3)) 11562f2b60a0SDavid Wu 11572f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RMII_GATE(id) GRF_BIT(5 * (id) + 1) 11582f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RMII_NOGATE(id) GRF_CLR_BIT(5 * (id) + 1) 11592f2b60a0SDavid Wu 11602f2b60a0SDavid Wu static void rk3588_set_to_rgmii(struct rk_priv_data *bsp_priv, 11612f2b60a0SDavid Wu int tx_delay, int rx_delay) 11622f2b60a0SDavid Wu { 11632f2b60a0SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 11642f2b60a0SDavid Wu u32 offset_con, id = bsp_priv->id; 11652f2b60a0SDavid Wu 11662f2b60a0SDavid Wu if (IS_ERR(bsp_priv->grf) || IS_ERR(bsp_priv->php_grf)) { 11672f2b60a0SDavid Wu dev_err(dev, "Missing rockchip,grf or rockchip,php_grf property\n"); 11682f2b60a0SDavid Wu return; 11692f2b60a0SDavid Wu } 11702f2b60a0SDavid Wu 11712f2b60a0SDavid Wu offset_con = bsp_priv->id == 1 ? RK3588_GRF_GMAC_CON9 : 11722f2b60a0SDavid Wu RK3588_GRF_GMAC_CON8; 11732f2b60a0SDavid Wu 11742f2b60a0SDavid Wu regmap_write(bsp_priv->php_grf, RK3588_GRF_GMAC_CON0, 11752f2b60a0SDavid Wu RK3588_GMAC_PHY_INTF_SEL_RGMII(id)); 11762f2b60a0SDavid Wu 11772f2b60a0SDavid Wu regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, 11782f2b60a0SDavid Wu RK3588_GMAC_CLK_RGMII_MODE(id)); 11792f2b60a0SDavid Wu 11802f2b60a0SDavid Wu regmap_write(bsp_priv->grf, RK3588_GRF_GMAC_CON7, 11812f2b60a0SDavid Wu RK3588_GMAC_RXCLK_DLY_ENABLE(id) | 11822f2b60a0SDavid Wu RK3588_GMAC_TXCLK_DLY_ENABLE(id)); 11832f2b60a0SDavid Wu 11842f2b60a0SDavid Wu regmap_write(bsp_priv->grf, offset_con, 11852f2b60a0SDavid Wu RK3588_GMAC_CLK_RX_DL_CFG(rx_delay) | 11862f2b60a0SDavid Wu RK3588_GMAC_CLK_TX_DL_CFG(tx_delay)); 11872f2b60a0SDavid Wu } 11882f2b60a0SDavid Wu 11892f2b60a0SDavid Wu static void rk3588_set_to_rmii(struct rk_priv_data *bsp_priv) 11902f2b60a0SDavid Wu { 11912f2b60a0SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 11922f2b60a0SDavid Wu 11932f2b60a0SDavid Wu if (IS_ERR(bsp_priv->php_grf)) { 11942f2b60a0SDavid Wu dev_err(dev, "%s: Missing rockchip,php_grf property\n", __func__); 11952f2b60a0SDavid Wu return; 11962f2b60a0SDavid Wu } 11972f2b60a0SDavid Wu 11982f2b60a0SDavid Wu regmap_write(bsp_priv->php_grf, RK3588_GRF_GMAC_CON0, 11992f2b60a0SDavid Wu RK3588_GMAC_PHY_INTF_SEL_RMII(bsp_priv->id)); 12002f2b60a0SDavid Wu 12012f2b60a0SDavid Wu regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, 12022f2b60a0SDavid Wu RK3588_GMAC_CLK_RMII_MODE(bsp_priv->id)); 12032f2b60a0SDavid Wu } 12042f2b60a0SDavid Wu 12052f2b60a0SDavid Wu static void rk3588_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed) 12062f2b60a0SDavid Wu { 12072f2b60a0SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 12082f2b60a0SDavid Wu unsigned int val = 0, id = bsp_priv->id; 12092f2b60a0SDavid Wu 12102f2b60a0SDavid Wu switch (speed) { 12112f2b60a0SDavid Wu case 10: 12122f2b60a0SDavid Wu if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) 12132f2b60a0SDavid Wu val = RK3588_GMA_CLK_RMII_DIV20(id); 12142f2b60a0SDavid Wu else 12152f2b60a0SDavid Wu val = RK3588_GMAC_CLK_RGMII_DIV50(id); 12162f2b60a0SDavid Wu break; 12172f2b60a0SDavid Wu case 100: 12182f2b60a0SDavid Wu if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) 12192f2b60a0SDavid Wu val = RK3588_GMA_CLK_RMII_DIV2(id); 12202f2b60a0SDavid Wu else 12212f2b60a0SDavid Wu val = RK3588_GMAC_CLK_RGMII_DIV5(id); 12222f2b60a0SDavid Wu break; 12232f2b60a0SDavid Wu case 1000: 12242f2b60a0SDavid Wu if (bsp_priv->phy_iface != PHY_INTERFACE_MODE_RMII) 12252f2b60a0SDavid Wu val = RK3588_GMAC_CLK_RGMII_DIV1(id); 12262f2b60a0SDavid Wu else 12272f2b60a0SDavid Wu goto err; 12282f2b60a0SDavid Wu break; 12292f2b60a0SDavid Wu default: 12302f2b60a0SDavid Wu goto err; 12312f2b60a0SDavid Wu } 12322f2b60a0SDavid Wu 12332f2b60a0SDavid Wu regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, val); 12342f2b60a0SDavid Wu 12352f2b60a0SDavid Wu return; 12362f2b60a0SDavid Wu err: 12372f2b60a0SDavid Wu dev_err(dev, "unknown speed value for GMAC speed=%d", speed); 12382f2b60a0SDavid Wu } 12392f2b60a0SDavid Wu 12402f2b60a0SDavid Wu static void rk3588_set_clock_selection(struct rk_priv_data *bsp_priv, bool input, 12412f2b60a0SDavid Wu bool enable) 12422f2b60a0SDavid Wu { 1243*78a60497SDetlev Casanova unsigned int val = input ? RK3588_GMAC_CLK_SELECT_IO(bsp_priv->id) : 1244*78a60497SDetlev Casanova RK3588_GMAC_CLK_SELECT_CRU(bsp_priv->id); 12452f2b60a0SDavid Wu 12462f2b60a0SDavid Wu val |= enable ? RK3588_GMAC_CLK_RMII_NOGATE(bsp_priv->id) : 12472f2b60a0SDavid Wu RK3588_GMAC_CLK_RMII_GATE(bsp_priv->id); 12482f2b60a0SDavid Wu 12492f2b60a0SDavid Wu regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, val); 12502f2b60a0SDavid Wu } 12512f2b60a0SDavid Wu 12522f2b60a0SDavid Wu static const struct rk_gmac_ops rk3588_ops = { 12532f2b60a0SDavid Wu .set_to_rgmii = rk3588_set_to_rgmii, 12542f2b60a0SDavid Wu .set_to_rmii = rk3588_set_to_rmii, 12552f2b60a0SDavid Wu .set_rgmii_speed = rk3588_set_gmac_speed, 12562f2b60a0SDavid Wu .set_rmii_speed = rk3588_set_gmac_speed, 12572f2b60a0SDavid Wu .set_clock_selection = rk3588_set_clock_selection, 125888619e77SBenjamin Gaignard .regs_valid = true, 125988619e77SBenjamin Gaignard .regs = { 126088619e77SBenjamin Gaignard 0xfe1b0000, /* gmac0 */ 126188619e77SBenjamin Gaignard 0xfe1c0000, /* gmac1 */ 126288619e77SBenjamin Gaignard 0x0, /* sentinel */ 126388619e77SBenjamin Gaignard }, 12642f2b60a0SDavid Wu }; 12652f2b60a0SDavid Wu 126689c9c163SDavid Wu #define RV1108_GRF_GMAC_CON0 0X0900 126789c9c163SDavid Wu 126889c9c163SDavid Wu /* RV1108_GRF_GMAC_CON0 */ 126989c9c163SDavid Wu #define RV1108_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \ 127089c9c163SDavid Wu GRF_BIT(6)) 127189c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL GRF_BIT(3) 127289c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3) 127389c9c163SDavid Wu #define RV1108_GMAC_SPEED_10M GRF_CLR_BIT(2) 127489c9c163SDavid Wu #define RV1108_GMAC_SPEED_100M GRF_BIT(2) 127589c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_25M GRF_BIT(7) 127689c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7) 127789c9c163SDavid Wu 127889c9c163SDavid Wu static void rv1108_set_to_rmii(struct rk_priv_data *bsp_priv) 127989c9c163SDavid Wu { 128089c9c163SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 128189c9c163SDavid Wu 128289c9c163SDavid Wu if (IS_ERR(bsp_priv->grf)) { 128389c9c163SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 128489c9c163SDavid Wu return; 128589c9c163SDavid Wu } 128689c9c163SDavid Wu 128789c9c163SDavid Wu regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0, 128889c9c163SDavid Wu RV1108_GMAC_PHY_INTF_SEL_RMII); 128989c9c163SDavid Wu } 129089c9c163SDavid Wu 129189c9c163SDavid Wu static void rv1108_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 129289c9c163SDavid Wu { 129389c9c163SDavid Wu struct device *dev = &bsp_priv->pdev->dev; 129489c9c163SDavid Wu 129589c9c163SDavid Wu if (IS_ERR(bsp_priv->grf)) { 129689c9c163SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 129789c9c163SDavid Wu return; 129889c9c163SDavid Wu } 129989c9c163SDavid Wu 130089c9c163SDavid Wu if (speed == 10) { 130189c9c163SDavid Wu regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0, 130289c9c163SDavid Wu RV1108_GMAC_RMII_CLK_2_5M | 130389c9c163SDavid Wu RV1108_GMAC_SPEED_10M); 130489c9c163SDavid Wu } else if (speed == 100) { 130589c9c163SDavid Wu regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0, 130689c9c163SDavid Wu RV1108_GMAC_RMII_CLK_25M | 130789c9c163SDavid Wu RV1108_GMAC_SPEED_100M); 130889c9c163SDavid Wu } else { 130989c9c163SDavid Wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed); 131089c9c163SDavid Wu } 131189c9c163SDavid Wu } 131289c9c163SDavid Wu 131389c9c163SDavid Wu static const struct rk_gmac_ops rv1108_ops = { 131489c9c163SDavid Wu .set_to_rmii = rv1108_set_to_rmii, 131589c9c163SDavid Wu .set_rmii_speed = rv1108_set_rmii_speed, 131689c9c163SDavid Wu }; 131789c9c163SDavid Wu 1318c931b060SAnand Moon #define RV1126_GRF_GMAC_CON0 0X0070 1319c931b060SAnand Moon #define RV1126_GRF_GMAC_CON1 0X0074 1320c931b060SAnand Moon #define RV1126_GRF_GMAC_CON2 0X0078 1321c931b060SAnand Moon 1322c931b060SAnand Moon /* RV1126_GRF_GMAC_CON0 */ 1323c931b060SAnand Moon #define RV1126_GMAC_PHY_INTF_SEL_RGMII \ 1324c931b060SAnand Moon (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6)) 1325c931b060SAnand Moon #define RV1126_GMAC_PHY_INTF_SEL_RMII \ 1326c931b060SAnand Moon (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6)) 1327c931b060SAnand Moon #define RV1126_GMAC_FLOW_CTRL GRF_BIT(7) 1328c931b060SAnand Moon #define RV1126_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(7) 1329c931b060SAnand Moon #define RV1126_GMAC_M0_RXCLK_DLY_ENABLE GRF_BIT(1) 1330c931b060SAnand Moon #define RV1126_GMAC_M0_RXCLK_DLY_DISABLE GRF_CLR_BIT(1) 1331c931b060SAnand Moon #define RV1126_GMAC_M0_TXCLK_DLY_ENABLE GRF_BIT(0) 1332c931b060SAnand Moon #define RV1126_GMAC_M0_TXCLK_DLY_DISABLE GRF_CLR_BIT(0) 1333c931b060SAnand Moon #define RV1126_GMAC_M1_RXCLK_DLY_ENABLE GRF_BIT(3) 1334c931b060SAnand Moon #define RV1126_GMAC_M1_RXCLK_DLY_DISABLE GRF_CLR_BIT(3) 1335c931b060SAnand Moon #define RV1126_GMAC_M1_TXCLK_DLY_ENABLE GRF_BIT(2) 1336c931b060SAnand Moon #define RV1126_GMAC_M1_TXCLK_DLY_DISABLE GRF_CLR_BIT(2) 1337c931b060SAnand Moon 1338c931b060SAnand Moon /* RV1126_GRF_GMAC_CON1 */ 1339c931b060SAnand Moon #define RV1126_GMAC_M0_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 1340c931b060SAnand Moon #define RV1126_GMAC_M0_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 1341c931b060SAnand Moon /* RV1126_GRF_GMAC_CON2 */ 1342c931b060SAnand Moon #define RV1126_GMAC_M1_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) 1343c931b060SAnand Moon #define RV1126_GMAC_M1_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) 1344c931b060SAnand Moon 1345c931b060SAnand Moon static void rv1126_set_to_rgmii(struct rk_priv_data *bsp_priv, 1346c931b060SAnand Moon int tx_delay, int rx_delay) 1347c931b060SAnand Moon { 1348c931b060SAnand Moon struct device *dev = &bsp_priv->pdev->dev; 1349c931b060SAnand Moon 1350c931b060SAnand Moon if (IS_ERR(bsp_priv->grf)) { 1351c931b060SAnand Moon dev_err(dev, "Missing rockchip,grf property\n"); 1352c931b060SAnand Moon return; 1353c931b060SAnand Moon } 1354c931b060SAnand Moon 1355c931b060SAnand Moon regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON0, 1356c931b060SAnand Moon RV1126_GMAC_PHY_INTF_SEL_RGMII | 1357c931b060SAnand Moon RV1126_GMAC_M0_RXCLK_DLY_ENABLE | 1358c931b060SAnand Moon RV1126_GMAC_M0_TXCLK_DLY_ENABLE | 1359c931b060SAnand Moon RV1126_GMAC_M1_RXCLK_DLY_ENABLE | 1360c931b060SAnand Moon RV1126_GMAC_M1_TXCLK_DLY_ENABLE); 1361c931b060SAnand Moon 1362c931b060SAnand Moon regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON1, 1363c931b060SAnand Moon RV1126_GMAC_M0_CLK_RX_DL_CFG(rx_delay) | 1364c931b060SAnand Moon RV1126_GMAC_M0_CLK_TX_DL_CFG(tx_delay)); 1365c931b060SAnand Moon 1366c931b060SAnand Moon regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON2, 1367c931b060SAnand Moon RV1126_GMAC_M1_CLK_RX_DL_CFG(rx_delay) | 1368c931b060SAnand Moon RV1126_GMAC_M1_CLK_TX_DL_CFG(tx_delay)); 1369c931b060SAnand Moon } 1370c931b060SAnand Moon 1371c931b060SAnand Moon static void rv1126_set_to_rmii(struct rk_priv_data *bsp_priv) 1372c931b060SAnand Moon { 1373c931b060SAnand Moon struct device *dev = &bsp_priv->pdev->dev; 1374c931b060SAnand Moon 1375c931b060SAnand Moon if (IS_ERR(bsp_priv->grf)) { 1376c931b060SAnand Moon dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); 1377c931b060SAnand Moon return; 1378c931b060SAnand Moon } 1379c931b060SAnand Moon 1380c931b060SAnand Moon regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON0, 1381c931b060SAnand Moon RV1126_GMAC_PHY_INTF_SEL_RMII); 1382c931b060SAnand Moon } 1383c931b060SAnand Moon 1384c931b060SAnand Moon static void rv1126_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) 1385c931b060SAnand Moon { 1386ea449f7fSSebastian Reichel struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk; 1387c931b060SAnand Moon struct device *dev = &bsp_priv->pdev->dev; 1388c931b060SAnand Moon unsigned long rate; 1389c931b060SAnand Moon int ret; 1390c931b060SAnand Moon 1391c931b060SAnand Moon switch (speed) { 1392c931b060SAnand Moon case 10: 1393c931b060SAnand Moon rate = 2500000; 1394c931b060SAnand Moon break; 1395c931b060SAnand Moon case 100: 1396c931b060SAnand Moon rate = 25000000; 1397c931b060SAnand Moon break; 1398c931b060SAnand Moon case 1000: 1399c931b060SAnand Moon rate = 125000000; 1400c931b060SAnand Moon break; 1401c931b060SAnand Moon default: 1402c931b060SAnand Moon dev_err(dev, "unknown speed value for RGMII speed=%d", speed); 1403c931b060SAnand Moon return; 1404c931b060SAnand Moon } 1405c931b060SAnand Moon 1406ea449f7fSSebastian Reichel ret = clk_set_rate(clk_mac_speed, rate); 1407c931b060SAnand Moon if (ret) 1408c931b060SAnand Moon dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n", 1409c931b060SAnand Moon __func__, rate, ret); 1410c931b060SAnand Moon } 1411c931b060SAnand Moon 1412c931b060SAnand Moon static void rv1126_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) 1413c931b060SAnand Moon { 1414ea449f7fSSebastian Reichel struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk; 1415c931b060SAnand Moon struct device *dev = &bsp_priv->pdev->dev; 1416c931b060SAnand Moon unsigned long rate; 1417c931b060SAnand Moon int ret; 1418c931b060SAnand Moon 1419c931b060SAnand Moon switch (speed) { 1420c931b060SAnand Moon case 10: 1421c931b060SAnand Moon rate = 2500000; 1422c931b060SAnand Moon break; 1423c931b060SAnand Moon case 100: 1424c931b060SAnand Moon rate = 25000000; 1425c931b060SAnand Moon break; 1426c931b060SAnand Moon default: 1427c931b060SAnand Moon dev_err(dev, "unknown speed value for RGMII speed=%d", speed); 1428c931b060SAnand Moon return; 1429c931b060SAnand Moon } 1430c931b060SAnand Moon 1431ea449f7fSSebastian Reichel ret = clk_set_rate(clk_mac_speed, rate); 1432c931b060SAnand Moon if (ret) 1433c931b060SAnand Moon dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n", 1434c931b060SAnand Moon __func__, rate, ret); 1435c931b060SAnand Moon } 1436c931b060SAnand Moon 1437c931b060SAnand Moon static const struct rk_gmac_ops rv1126_ops = { 1438c931b060SAnand Moon .set_to_rgmii = rv1126_set_to_rgmii, 1439c931b060SAnand Moon .set_to_rmii = rv1126_set_to_rmii, 1440c931b060SAnand Moon .set_rgmii_speed = rv1126_set_rgmii_speed, 1441c931b060SAnand Moon .set_rmii_speed = rv1126_set_rmii_speed, 1442c931b060SAnand Moon }; 1443c931b060SAnand Moon 1444fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON0 0xb00 1445fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON1 0xb04 1446fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON2 0xb08 1447fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON3 0xb0c 1448fecd4d7eSDavid Wu 1449fecd4d7eSDavid Wu #define RK_MACPHY_ENABLE GRF_BIT(0) 1450fecd4d7eSDavid Wu #define RK_MACPHY_DISABLE GRF_CLR_BIT(0) 1451fecd4d7eSDavid Wu #define RK_MACPHY_CFG_CLK_50M GRF_BIT(14) 1452fecd4d7eSDavid Wu #define RK_GMAC2PHY_RMII_MODE (GRF_BIT(6) | GRF_CLR_BIT(7)) 1453fecd4d7eSDavid Wu #define RK_GRF_CON2_MACPHY_ID HIWORD_UPDATE(0x1234, 0xffff, 0) 1454fecd4d7eSDavid Wu #define RK_GRF_CON3_MACPHY_ID HIWORD_UPDATE(0x35, 0x3f, 0) 1455fecd4d7eSDavid Wu 1456fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerup(struct rk_priv_data *priv) 14577ad269eaSRoger Chen { 1458fecd4d7eSDavid Wu if (priv->ops->integrated_phy_powerup) 1459fecd4d7eSDavid Wu priv->ops->integrated_phy_powerup(priv); 1460fecd4d7eSDavid Wu 1461fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M); 1462fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE); 1463fecd4d7eSDavid Wu 1464fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID); 1465fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID); 1466fecd4d7eSDavid Wu 1467fecd4d7eSDavid Wu if (priv->phy_reset) { 1468fecd4d7eSDavid Wu /* PHY needs to be disabled before trying to reset it */ 1469fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE); 1470fecd4d7eSDavid Wu if (priv->phy_reset) 1471fecd4d7eSDavid Wu reset_control_assert(priv->phy_reset); 1472fecd4d7eSDavid Wu usleep_range(10, 20); 1473fecd4d7eSDavid Wu if (priv->phy_reset) 1474fecd4d7eSDavid Wu reset_control_deassert(priv->phy_reset); 1475fecd4d7eSDavid Wu usleep_range(10, 20); 1476fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE); 1477fecd4d7eSDavid Wu msleep(30); 1478fecd4d7eSDavid Wu } 1479fecd4d7eSDavid Wu } 1480fecd4d7eSDavid Wu 1481fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerdown(struct rk_priv_data *priv) 1482fecd4d7eSDavid Wu { 1483fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE); 1484fecd4d7eSDavid Wu if (priv->phy_reset) 1485fecd4d7eSDavid Wu reset_control_assert(priv->phy_reset); 1486fecd4d7eSDavid Wu } 1487fecd4d7eSDavid Wu 1488fecd4d7eSDavid Wu static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat) 1489fecd4d7eSDavid Wu { 1490fecd4d7eSDavid Wu struct rk_priv_data *bsp_priv = plat->bsp_priv; 14917ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 1492ea449f7fSSebastian Reichel int phy_iface = bsp_priv->phy_iface; 1493ea449f7fSSebastian Reichel int i, j, ret; 14947ad269eaSRoger Chen 14957ad269eaSRoger Chen bsp_priv->clk_enabled = false; 14967ad269eaSRoger Chen 1497ea449f7fSSebastian Reichel bsp_priv->num_clks = ARRAY_SIZE(rk_clocks); 1498ea449f7fSSebastian Reichel if (phy_iface == PHY_INTERFACE_MODE_RMII) 1499ea449f7fSSebastian Reichel bsp_priv->num_clks += ARRAY_SIZE(rk_rmii_clocks); 15007ad269eaSRoger Chen 1501ea449f7fSSebastian Reichel bsp_priv->clks = devm_kcalloc(dev, bsp_priv->num_clks, 1502ea449f7fSSebastian Reichel sizeof(*bsp_priv->clks), GFP_KERNEL); 1503ea449f7fSSebastian Reichel if (!bsp_priv->clks) 1504ea449f7fSSebastian Reichel return -ENOMEM; 15057ad269eaSRoger Chen 1506ea449f7fSSebastian Reichel for (i = 0; i < ARRAY_SIZE(rk_clocks); i++) 1507ea449f7fSSebastian Reichel bsp_priv->clks[i].id = rk_clocks[i]; 15087ad269eaSRoger Chen 1509ea449f7fSSebastian Reichel if (phy_iface == PHY_INTERFACE_MODE_RMII) { 1510ea449f7fSSebastian Reichel for (j = 0; j < ARRAY_SIZE(rk_rmii_clocks); j++) 1511ea449f7fSSebastian Reichel bsp_priv->clks[i++].id = rk_rmii_clocks[j]; 1512ea449f7fSSebastian Reichel } 15137ad269eaSRoger Chen 1514ea449f7fSSebastian Reichel ret = devm_clk_bulk_get_optional(dev, bsp_priv->num_clks, 1515ea449f7fSSebastian Reichel bsp_priv->clks); 1516ea449f7fSSebastian Reichel if (ret) 1517ea449f7fSSebastian Reichel return dev_err_probe(dev, ret, "Failed to get clocks\n"); 1518ea449f7fSSebastian Reichel 1519ea449f7fSSebastian Reichel /* "stmmaceth" will be enabled by the core */ 15207ad269eaSRoger Chen bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth"); 1521ea449f7fSSebastian Reichel ret = PTR_ERR_OR_ZERO(bsp_priv->clk_mac); 1522ea449f7fSSebastian Reichel if (ret) 1523ea449f7fSSebastian Reichel return dev_err_probe(dev, ret, "Cannot get stmmaceth clock\n"); 152423c94d63SDavid Wu 15257ad269eaSRoger Chen if (bsp_priv->clock_input) { 1526d42202dcSRomain Perier dev_info(dev, "clock input from PHY\n"); 1527ea449f7fSSebastian Reichel } else if (phy_iface == PHY_INTERFACE_MODE_RMII) { 1528c48fa33cSHeiko Stübner clk_set_rate(bsp_priv->clk_mac, 50000000); 15297ad269eaSRoger Chen } 15307ad269eaSRoger Chen 1531fecd4d7eSDavid Wu if (plat->phy_node && bsp_priv->integrated_phy) { 1532fecd4d7eSDavid Wu bsp_priv->clk_phy = of_clk_get(plat->phy_node, 0); 1533ea449f7fSSebastian Reichel ret = PTR_ERR_OR_ZERO(bsp_priv->clk_phy); 1534ea449f7fSSebastian Reichel if (ret) 1535ea449f7fSSebastian Reichel return dev_err_probe(dev, ret, "Cannot get PHY clock\n"); 1536fecd4d7eSDavid Wu clk_set_rate(bsp_priv->clk_phy, 50000000); 1537fecd4d7eSDavid Wu } 1538fecd4d7eSDavid Wu 15397ad269eaSRoger Chen return 0; 15407ad269eaSRoger Chen } 15417ad269eaSRoger Chen 15427ad269eaSRoger Chen static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable) 15437ad269eaSRoger Chen { 1544ea449f7fSSebastian Reichel int ret; 15457ad269eaSRoger Chen 15467ad269eaSRoger Chen if (enable) { 15477ad269eaSRoger Chen if (!bsp_priv->clk_enabled) { 1548ea449f7fSSebastian Reichel ret = clk_bulk_prepare_enable(bsp_priv->num_clks, 1549ea449f7fSSebastian Reichel bsp_priv->clks); 1550ea449f7fSSebastian Reichel if (ret) 1551ea449f7fSSebastian Reichel return ret; 15527ad269eaSRoger Chen 1553ea449f7fSSebastian Reichel ret = clk_prepare_enable(bsp_priv->clk_phy); 1554ea449f7fSSebastian Reichel if (ret) 1555ea449f7fSSebastian Reichel return ret; 155623c94d63SDavid Wu 15572f2b60a0SDavid Wu if (bsp_priv->ops && bsp_priv->ops->set_clock_selection) 15582f2b60a0SDavid Wu bsp_priv->ops->set_clock_selection(bsp_priv, 15592f2b60a0SDavid Wu bsp_priv->clock_input, true); 15602f2b60a0SDavid Wu 15617ad269eaSRoger Chen mdelay(5); 15627ad269eaSRoger Chen bsp_priv->clk_enabled = true; 15637ad269eaSRoger Chen } 15647ad269eaSRoger Chen } else { 15657ad269eaSRoger Chen if (bsp_priv->clk_enabled) { 1566ea449f7fSSebastian Reichel clk_bulk_disable_unprepare(bsp_priv->num_clks, 1567ea449f7fSSebastian Reichel bsp_priv->clks); 1568fecd4d7eSDavid Wu clk_disable_unprepare(bsp_priv->clk_phy); 1569fecd4d7eSDavid Wu 15702f2b60a0SDavid Wu if (bsp_priv->ops && bsp_priv->ops->set_clock_selection) 15712f2b60a0SDavid Wu bsp_priv->ops->set_clock_selection(bsp_priv, 15722f2b60a0SDavid Wu bsp_priv->clock_input, false); 1573ea449f7fSSebastian Reichel 15747ad269eaSRoger Chen bsp_priv->clk_enabled = false; 15757ad269eaSRoger Chen } 15767ad269eaSRoger Chen } 15777ad269eaSRoger Chen 15787ad269eaSRoger Chen return 0; 15797ad269eaSRoger Chen } 15807ad269eaSRoger Chen 15817ad269eaSRoger Chen static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable) 15827ad269eaSRoger Chen { 15832e12f536SRomain Perier struct regulator *ldo = bsp_priv->regulator; 15847ad269eaSRoger Chen int ret; 15857ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 15867ad269eaSRoger Chen 15877ad269eaSRoger Chen if (enable) { 15887ad269eaSRoger Chen ret = regulator_enable(ldo); 15892e12f536SRomain Perier if (ret) 1590d42202dcSRomain Perier dev_err(dev, "fail to enable phy-supply\n"); 15917ad269eaSRoger Chen } else { 15927ad269eaSRoger Chen ret = regulator_disable(ldo); 15932e12f536SRomain Perier if (ret) 1594d42202dcSRomain Perier dev_err(dev, "fail to disable phy-supply\n"); 15957ad269eaSRoger Chen } 15967ad269eaSRoger Chen 15977ad269eaSRoger Chen return 0; 15987ad269eaSRoger Chen } 15997ad269eaSRoger Chen 16000fb98db1SHeiko Stübner static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev, 1601fecd4d7eSDavid Wu struct plat_stmmacenet_data *plat, 160292c2588fSJoachim Eastwood const struct rk_gmac_ops *ops) 16037ad269eaSRoger Chen { 16047ad269eaSRoger Chen struct rk_priv_data *bsp_priv; 16057ad269eaSRoger Chen struct device *dev = &pdev->dev; 16063bb3d6b1SDavid Wu struct resource *res; 16077ad269eaSRoger Chen int ret; 16087ad269eaSRoger Chen const char *strings = NULL; 16097ad269eaSRoger Chen int value; 16107ad269eaSRoger Chen 16117ad269eaSRoger Chen bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL); 16127ad269eaSRoger Chen if (!bsp_priv) 16137ad269eaSRoger Chen return ERR_PTR(-ENOMEM); 16147ad269eaSRoger Chen 16150c65b2b9SAndrew Lunn of_get_phy_mode(dev->of_node, &bsp_priv->phy_iface); 16160fb98db1SHeiko Stübner bsp_priv->ops = ops; 16177ad269eaSRoger Chen 16183bb3d6b1SDavid Wu /* Some SoCs have multiple MAC controllers, which need 16193bb3d6b1SDavid Wu * to be distinguished. 16203bb3d6b1SDavid Wu */ 16213bb3d6b1SDavid Wu res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 16220546b224SJohn Keeping if (res && ops->regs_valid) { 16233bb3d6b1SDavid Wu int i = 0; 16243bb3d6b1SDavid Wu 16253bb3d6b1SDavid Wu while (ops->regs[i]) { 16263bb3d6b1SDavid Wu if (ops->regs[i] == res->start) { 16273bb3d6b1SDavid Wu bsp_priv->id = i; 16283bb3d6b1SDavid Wu break; 16293bb3d6b1SDavid Wu } 16303bb3d6b1SDavid Wu i++; 16313bb3d6b1SDavid Wu } 16323bb3d6b1SDavid Wu } 16333bb3d6b1SDavid Wu 1634db219732SSebastian Reichel bsp_priv->regulator = devm_regulator_get(dev, "phy"); 16352e12f536SRomain Perier if (IS_ERR(bsp_priv->regulator)) { 1636db219732SSebastian Reichel ret = PTR_ERR(bsp_priv->regulator); 1637db219732SSebastian Reichel dev_err_probe(dev, ret, "failed to get phy regulator\n"); 1638db219732SSebastian Reichel return ERR_PTR(ret); 16397ad269eaSRoger Chen } 16407ad269eaSRoger Chen 16417ad269eaSRoger Chen ret = of_property_read_string(dev->of_node, "clock_in_out", &strings); 16427ad269eaSRoger Chen if (ret) { 1643d42202dcSRomain Perier dev_err(dev, "Can not read property: clock_in_out.\n"); 16447ad269eaSRoger Chen bsp_priv->clock_input = true; 16457ad269eaSRoger Chen } else { 1646d42202dcSRomain Perier dev_info(dev, "clock input or output? (%s).\n", 1647d42202dcSRomain Perier strings); 16487ad269eaSRoger Chen if (!strcmp(strings, "input")) 16497ad269eaSRoger Chen bsp_priv->clock_input = true; 16507ad269eaSRoger Chen else 16517ad269eaSRoger Chen bsp_priv->clock_input = false; 16527ad269eaSRoger Chen } 16537ad269eaSRoger Chen 16547ad269eaSRoger Chen ret = of_property_read_u32(dev->of_node, "tx_delay", &value); 16557ad269eaSRoger Chen if (ret) { 16567ad269eaSRoger Chen bsp_priv->tx_delay = 0x30; 1657d42202dcSRomain Perier dev_err(dev, "Can not read property: tx_delay."); 1658d42202dcSRomain Perier dev_err(dev, "set tx_delay to 0x%x\n", 1659d42202dcSRomain Perier bsp_priv->tx_delay); 16607ad269eaSRoger Chen } else { 1661d42202dcSRomain Perier dev_info(dev, "TX delay(0x%x).\n", value); 16627ad269eaSRoger Chen bsp_priv->tx_delay = value; 16637ad269eaSRoger Chen } 16647ad269eaSRoger Chen 16657ad269eaSRoger Chen ret = of_property_read_u32(dev->of_node, "rx_delay", &value); 16667ad269eaSRoger Chen if (ret) { 16677ad269eaSRoger Chen bsp_priv->rx_delay = 0x10; 1668d42202dcSRomain Perier dev_err(dev, "Can not read property: rx_delay."); 1669d42202dcSRomain Perier dev_err(dev, "set rx_delay to 0x%x\n", 1670d42202dcSRomain Perier bsp_priv->rx_delay); 16717ad269eaSRoger Chen } else { 1672d42202dcSRomain Perier dev_info(dev, "RX delay(0x%x).\n", value); 16737ad269eaSRoger Chen bsp_priv->rx_delay = value; 16747ad269eaSRoger Chen } 16757ad269eaSRoger Chen 16767ad269eaSRoger Chen bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node, 16777ad269eaSRoger Chen "rockchip,grf"); 16782f2b60a0SDavid Wu bsp_priv->php_grf = syscon_regmap_lookup_by_phandle(dev->of_node, 16792f2b60a0SDavid Wu "rockchip,php-grf"); 16807ad269eaSRoger Chen 1681fecd4d7eSDavid Wu if (plat->phy_node) { 1682fecd4d7eSDavid Wu bsp_priv->integrated_phy = of_property_read_bool(plat->phy_node, 1683fecd4d7eSDavid Wu "phy-is-integrated"); 1684fecd4d7eSDavid Wu if (bsp_priv->integrated_phy) { 1685fecd4d7eSDavid Wu bsp_priv->phy_reset = of_reset_control_get(plat->phy_node, NULL); 1686fecd4d7eSDavid Wu if (IS_ERR(bsp_priv->phy_reset)) { 1687fecd4d7eSDavid Wu dev_err(&pdev->dev, "No PHY reset control found.\n"); 1688fecd4d7eSDavid Wu bsp_priv->phy_reset = NULL; 1689fecd4d7eSDavid Wu } 1690fecd4d7eSDavid Wu } 1691fecd4d7eSDavid Wu } 1692fecd4d7eSDavid Wu dev_info(dev, "integrated PHY? (%s).\n", 1693fecd4d7eSDavid Wu bsp_priv->integrated_phy ? "yes" : "no"); 1694fecd4d7eSDavid Wu 1695fecd4d7eSDavid Wu bsp_priv->pdev = pdev; 169645383f52SRoger Chen 169745383f52SRoger Chen return bsp_priv; 169845383f52SRoger Chen } 169945383f52SRoger Chen 170037c80d15SDavid Wu static int rk_gmac_check_ops(struct rk_priv_data *bsp_priv) 170137c80d15SDavid Wu { 170237c80d15SDavid Wu switch (bsp_priv->phy_iface) { 170337c80d15SDavid Wu case PHY_INTERFACE_MODE_RGMII: 170437c80d15SDavid Wu case PHY_INTERFACE_MODE_RGMII_ID: 170537c80d15SDavid Wu case PHY_INTERFACE_MODE_RGMII_RXID: 170637c80d15SDavid Wu case PHY_INTERFACE_MODE_RGMII_TXID: 170737c80d15SDavid Wu if (!bsp_priv->ops->set_to_rgmii) 170837c80d15SDavid Wu return -EINVAL; 170937c80d15SDavid Wu break; 171037c80d15SDavid Wu case PHY_INTERFACE_MODE_RMII: 171137c80d15SDavid Wu if (!bsp_priv->ops->set_to_rmii) 171237c80d15SDavid Wu return -EINVAL; 171337c80d15SDavid Wu break; 171437c80d15SDavid Wu default: 171537c80d15SDavid Wu dev_err(&bsp_priv->pdev->dev, 171637c80d15SDavid Wu "unsupported interface %d", bsp_priv->phy_iface); 171737c80d15SDavid Wu } 171837c80d15SDavid Wu return 0; 171937c80d15SDavid Wu } 172037c80d15SDavid Wu 172145383f52SRoger Chen static int rk_gmac_powerup(struct rk_priv_data *bsp_priv) 172245383f52SRoger Chen { 172345383f52SRoger Chen int ret; 172445383f52SRoger Chen struct device *dev = &bsp_priv->pdev->dev; 172545383f52SRoger Chen 172637c80d15SDavid Wu ret = rk_gmac_check_ops(bsp_priv); 172737c80d15SDavid Wu if (ret) 172837c80d15SDavid Wu return ret; 172937c80d15SDavid Wu 1730f217bfdeSHeiko Stübner ret = gmac_clk_enable(bsp_priv, true); 1731f217bfdeSHeiko Stübner if (ret) 1732f217bfdeSHeiko Stübner return ret; 1733f217bfdeSHeiko Stübner 17347ad269eaSRoger Chen /*rmii or rgmii*/ 1735eaf70ad1SWadim Egorov switch (bsp_priv->phy_iface) { 1736eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII: 1737d42202dcSRomain Perier dev_info(dev, "init for RGMII\n"); 17380fb98db1SHeiko Stübner bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 17390fb98db1SHeiko Stübner bsp_priv->rx_delay); 1740eaf70ad1SWadim Egorov break; 1741eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_ID: 1742eaf70ad1SWadim Egorov dev_info(dev, "init for RGMII_ID\n"); 1743eaf70ad1SWadim Egorov bsp_priv->ops->set_to_rgmii(bsp_priv, 0, 0); 1744eaf70ad1SWadim Egorov break; 1745eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_RXID: 1746eaf70ad1SWadim Egorov dev_info(dev, "init for RGMII_RXID\n"); 1747eaf70ad1SWadim Egorov bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 0); 1748eaf70ad1SWadim Egorov break; 1749eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_TXID: 1750eaf70ad1SWadim Egorov dev_info(dev, "init for RGMII_TXID\n"); 1751eaf70ad1SWadim Egorov bsp_priv->ops->set_to_rgmii(bsp_priv, 0, bsp_priv->rx_delay); 1752eaf70ad1SWadim Egorov break; 1753eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RMII: 1754d42202dcSRomain Perier dev_info(dev, "init for RMII\n"); 17550fb98db1SHeiko Stübner bsp_priv->ops->set_to_rmii(bsp_priv); 1756eaf70ad1SWadim Egorov break; 1757eaf70ad1SWadim Egorov default: 1758d42202dcSRomain Perier dev_err(dev, "NO interface defined!\n"); 17597ad269eaSRoger Chen } 17607ad269eaSRoger Chen 17617ad269eaSRoger Chen ret = phy_power_on(bsp_priv, true); 1762c69c29a1SAlexey Khoroshilov if (ret) { 1763c69c29a1SAlexey Khoroshilov gmac_clk_enable(bsp_priv, false); 17647ad269eaSRoger Chen return ret; 1765c69c29a1SAlexey Khoroshilov } 17667ad269eaSRoger Chen 1767aec3f415SPunit Agrawal pm_runtime_get_sync(dev); 1768aec3f415SPunit Agrawal 1769fecd4d7eSDavid Wu if (bsp_priv->integrated_phy) 1770fecd4d7eSDavid Wu rk_gmac_integrated_phy_powerup(bsp_priv); 1771fecd4d7eSDavid Wu 17727ad269eaSRoger Chen return 0; 17737ad269eaSRoger Chen } 17747ad269eaSRoger Chen 1775229666c1SVincent Palatin static void rk_gmac_powerdown(struct rk_priv_data *gmac) 17767ad269eaSRoger Chen { 1777fecd4d7eSDavid Wu if (gmac->integrated_phy) 1778fecd4d7eSDavid Wu rk_gmac_integrated_phy_powerdown(gmac); 1779fecd4d7eSDavid Wu 1780aec3f415SPunit Agrawal pm_runtime_put_sync(&gmac->pdev->dev); 1781aec3f415SPunit Agrawal 17827ad269eaSRoger Chen phy_power_on(gmac, false); 17837ad269eaSRoger Chen gmac_clk_enable(gmac, false); 17847ad269eaSRoger Chen } 17857ad269eaSRoger Chen 17861fc04a0bSShenwei Wang static void rk_fix_speed(void *priv, unsigned int speed, unsigned int mode) 17877ad269eaSRoger Chen { 17887ad269eaSRoger Chen struct rk_priv_data *bsp_priv = priv; 17897ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev; 17907ad269eaSRoger Chen 1791eaf70ad1SWadim Egorov switch (bsp_priv->phy_iface) { 1792eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII: 1793eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_ID: 1794eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_RXID: 1795eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_TXID: 179637c80d15SDavid Wu if (bsp_priv->ops->set_rgmii_speed) 17970fb98db1SHeiko Stübner bsp_priv->ops->set_rgmii_speed(bsp_priv, speed); 1798eaf70ad1SWadim Egorov break; 1799eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RMII: 180037c80d15SDavid Wu if (bsp_priv->ops->set_rmii_speed) 18010fb98db1SHeiko Stübner bsp_priv->ops->set_rmii_speed(bsp_priv, speed); 1802eaf70ad1SWadim Egorov break; 1803eaf70ad1SWadim Egorov default: 18047ad269eaSRoger Chen dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface); 18057ad269eaSRoger Chen } 1806eaf70ad1SWadim Egorov } 18077ad269eaSRoger Chen 180827ffefd2SJoachim Eastwood static int rk_gmac_probe(struct platform_device *pdev) 180927ffefd2SJoachim Eastwood { 181027ffefd2SJoachim Eastwood struct plat_stmmacenet_data *plat_dat; 181127ffefd2SJoachim Eastwood struct stmmac_resources stmmac_res; 1812f529f182SJoachim Eastwood const struct rk_gmac_ops *data; 181327ffefd2SJoachim Eastwood int ret; 181427ffefd2SJoachim Eastwood 1815149adeddSJoachim Eastwood data = of_device_get_match_data(&pdev->dev); 1816149adeddSJoachim Eastwood if (!data) { 1817149adeddSJoachim Eastwood dev_err(&pdev->dev, "no of match data provided\n"); 1818149adeddSJoachim Eastwood return -EINVAL; 1819149adeddSJoachim Eastwood } 1820149adeddSJoachim Eastwood 182127ffefd2SJoachim Eastwood ret = stmmac_get_platform_resources(pdev, &stmmac_res); 182227ffefd2SJoachim Eastwood if (ret) 182327ffefd2SJoachim Eastwood return ret; 182427ffefd2SJoachim Eastwood 18258eee20e1SJisheng Zhang plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac); 182627ffefd2SJoachim Eastwood if (IS_ERR(plat_dat)) 182727ffefd2SJoachim Eastwood return PTR_ERR(plat_dat); 182827ffefd2SJoachim Eastwood 1829d6b06251SEzequiel Garcia /* If the stmmac is not already selected as gmac4, 1830d6b06251SEzequiel Garcia * then make sure we fallback to gmac. 1831d6b06251SEzequiel Garcia */ 1832d6b06251SEzequiel Garcia if (!plat_dat->has_gmac4) 183327ffefd2SJoachim Eastwood plat_dat->has_gmac = true; 183427ffefd2SJoachim Eastwood plat_dat->fix_mac_speed = rk_fix_speed; 183527ffefd2SJoachim Eastwood 1836fecd4d7eSDavid Wu plat_dat->bsp_priv = rk_gmac_setup(pdev, plat_dat, data); 18378eee20e1SJisheng Zhang if (IS_ERR(plat_dat->bsp_priv)) 18388eee20e1SJisheng Zhang return PTR_ERR(plat_dat->bsp_priv); 183927ffefd2SJoachim Eastwood 1840fecd4d7eSDavid Wu ret = rk_gmac_clk_init(plat_dat); 1841fecd4d7eSDavid Wu if (ret) 18428eee20e1SJisheng Zhang return ret; 1843fecd4d7eSDavid Wu 184407a5e769SJoachim Eastwood ret = rk_gmac_powerup(plat_dat->bsp_priv); 184527ffefd2SJoachim Eastwood if (ret) 18468eee20e1SJisheng Zhang return ret; 184727ffefd2SJoachim Eastwood 18482d222656SJohan Hovold ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); 18492d222656SJohan Hovold if (ret) 18502745529aSDavid S. Miller goto err_gmac_powerdown; 18512d222656SJohan Hovold 18522d222656SJohan Hovold return 0; 18532d222656SJohan Hovold 18542745529aSDavid S. Miller err_gmac_powerdown: 18552745529aSDavid S. Miller rk_gmac_powerdown(plat_dat->bsp_priv); 18562d222656SJohan Hovold 18572d222656SJohan Hovold return ret; 185827ffefd2SJoachim Eastwood } 185927ffefd2SJoachim Eastwood 1860903cc461SUwe Kleine-König static void rk_gmac_remove(struct platform_device *pdev) 18610de8c4c9SJoachim Eastwood { 18620de8c4c9SJoachim Eastwood struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(&pdev->dev); 1863ff0011cfSUwe Kleine-König 1864ff0011cfSUwe Kleine-König stmmac_dvr_remove(&pdev->dev); 18650de8c4c9SJoachim Eastwood 18660de8c4c9SJoachim Eastwood rk_gmac_powerdown(bsp_priv); 18670de8c4c9SJoachim Eastwood } 18680de8c4c9SJoachim Eastwood 18695619468aSJoachim Eastwood #ifdef CONFIG_PM_SLEEP 18705619468aSJoachim Eastwood static int rk_gmac_suspend(struct device *dev) 18715619468aSJoachim Eastwood { 18725619468aSJoachim Eastwood struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev); 18735619468aSJoachim Eastwood int ret = stmmac_suspend(dev); 18745619468aSJoachim Eastwood 18755619468aSJoachim Eastwood /* Keep the PHY up if we use Wake-on-Lan. */ 18765619468aSJoachim Eastwood if (!device_may_wakeup(dev)) { 18775619468aSJoachim Eastwood rk_gmac_powerdown(bsp_priv); 18785619468aSJoachim Eastwood bsp_priv->suspended = true; 18795619468aSJoachim Eastwood } 18805619468aSJoachim Eastwood 18815619468aSJoachim Eastwood return ret; 18825619468aSJoachim Eastwood } 18835619468aSJoachim Eastwood 18845619468aSJoachim Eastwood static int rk_gmac_resume(struct device *dev) 18855619468aSJoachim Eastwood { 18865619468aSJoachim Eastwood struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev); 18875619468aSJoachim Eastwood 18885619468aSJoachim Eastwood /* The PHY was up for Wake-on-Lan. */ 18895619468aSJoachim Eastwood if (bsp_priv->suspended) { 18905619468aSJoachim Eastwood rk_gmac_powerup(bsp_priv); 18915619468aSJoachim Eastwood bsp_priv->suspended = false; 18925619468aSJoachim Eastwood } 18935619468aSJoachim Eastwood 18945619468aSJoachim Eastwood return stmmac_resume(dev); 18955619468aSJoachim Eastwood } 18965619468aSJoachim Eastwood #endif /* CONFIG_PM_SLEEP */ 18975619468aSJoachim Eastwood 18985619468aSJoachim Eastwood static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume); 18995619468aSJoachim Eastwood 1900e0fb4013SJoachim Eastwood static const struct of_device_id rk_gmac_dwmac_match[] = { 190123c94d63SDavid Wu { .compatible = "rockchip,px30-gmac", .data = &px30_ops }, 190205946876SDavid Wu { .compatible = "rockchip,rk3128-gmac", .data = &rk3128_ops }, 1903e7ffd812SXing Zheng { .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops }, 1904f529f182SJoachim Eastwood { .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops }, 1905b4ac9456STobias Schramm { .compatible = "rockchip,rk3308-gmac", .data = &rk3308_ops }, 1906d4ff816eSdavid.wu { .compatible = "rockchip,rk3328-gmac", .data = &rk3328_ops }, 1907ba289af8SRoger Chen { .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops }, 1908f529f182SJoachim Eastwood { .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops }, 1909ba289af8SRoger Chen { .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops }, 19103bb3d6b1SDavid Wu { .compatible = "rockchip,rk3568-gmac", .data = &rk3568_ops }, 19112f2b60a0SDavid Wu { .compatible = "rockchip,rk3588-gmac", .data = &rk3588_ops }, 191289c9c163SDavid Wu { .compatible = "rockchip,rv1108-gmac", .data = &rv1108_ops }, 1913c931b060SAnand Moon { .compatible = "rockchip,rv1126-gmac", .data = &rv1126_ops }, 1914e0fb4013SJoachim Eastwood { } 1915e0fb4013SJoachim Eastwood }; 1916e0fb4013SJoachim Eastwood MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match); 1917e0fb4013SJoachim Eastwood 1918e0fb4013SJoachim Eastwood static struct platform_driver rk_gmac_dwmac_driver = { 191927ffefd2SJoachim Eastwood .probe = rk_gmac_probe, 1920903cc461SUwe Kleine-König .remove_new = rk_gmac_remove, 1921e0fb4013SJoachim Eastwood .driver = { 1922e0fb4013SJoachim Eastwood .name = "rk_gmac-dwmac", 19235619468aSJoachim Eastwood .pm = &rk_gmac_pm_ops, 1924e0fb4013SJoachim Eastwood .of_match_table = rk_gmac_dwmac_match, 1925e0fb4013SJoachim Eastwood }, 1926e0fb4013SJoachim Eastwood }; 1927e0fb4013SJoachim Eastwood module_platform_driver(rk_gmac_dwmac_driver); 1928e0fb4013SJoachim Eastwood 1929e0fb4013SJoachim Eastwood MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>"); 1930e0fb4013SJoachim Eastwood MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer"); 1931e0fb4013SJoachim Eastwood MODULE_LICENSE("GPL"); 1932