10125bcf0SSjoerd Simons /* 20125bcf0SSjoerd Simons * (C) Copyright 2015 Sjoerd Simons <sjoerd.simons@collabora.co.uk> 30125bcf0SSjoerd Simons * 40125bcf0SSjoerd Simons * SPDX-License-Identifier: GPL-2.0+ 50125bcf0SSjoerd Simons * 60125bcf0SSjoerd Simons * Rockchip GMAC ethernet IP driver for U-Boot 70125bcf0SSjoerd Simons */ 80125bcf0SSjoerd Simons 90125bcf0SSjoerd Simons #include <common.h> 100125bcf0SSjoerd Simons #include <dm.h> 110125bcf0SSjoerd Simons #include <clk.h> 120125bcf0SSjoerd Simons #include <phy.h> 130125bcf0SSjoerd Simons #include <syscon.h> 140125bcf0SSjoerd Simons #include <asm/io.h> 150125bcf0SSjoerd Simons #include <asm/arch/periph.h> 160125bcf0SSjoerd Simons #include <asm/arch/clock.h> 171f08aa1cSPhilipp Tomsich #include <asm/arch/hardware.h> 186f0a52e9SDavid Wu #ifdef CONFIG_DWC_ETH_QOS 19*33a014bdSDavid Wu #include <asm/arch/grf_rk3568.h> 20dcfb333aSDavid Wu #include <asm/arch/grf_rv1126.h> 216f0a52e9SDavid Wu #include "dwc_eth_qos.h" 226f0a52e9SDavid Wu #else 2318ae91c8SDavid Wu #include <asm/arch/grf_px30.h> 24ff86648dSDavid Wu #include <asm/arch/grf_rk1808.h> 25af166ffaSDavid Wu #include <asm/arch/grf_rk322x.h> 260125bcf0SSjoerd Simons #include <asm/arch/grf_rk3288.h> 2723adb58fSDavid Wu #include <asm/arch/grf_rk3308.h> 28c36b26c0SDavid Wu #include <asm/arch/grf_rk3328.h> 29793f2fd2SPhilipp Tomsich #include <asm/arch/grf_rk3368.h> 301f08aa1cSPhilipp Tomsich #include <asm/arch/grf_rk3399.h> 310a33ce65SDavid Wu #include <asm/arch/grf_rv1108.h> 320125bcf0SSjoerd Simons #include "designware.h" 336f0a52e9SDavid Wu #include <dt-bindings/clock/rk3288-cru.h> 346f0a52e9SDavid Wu #endif 356f0a52e9SDavid Wu #include <dm/pinctrl.h> 360125bcf0SSjoerd Simons 370125bcf0SSjoerd Simons DECLARE_GLOBAL_DATA_PTR; 380125bcf0SSjoerd Simons 396f0a52e9SDavid Wu struct rockchip_eth_dev { 406f0a52e9SDavid Wu #ifdef CONFIG_DWC_ETH_QOS 416f0a52e9SDavid Wu struct eqos_priv eqos; 426f0a52e9SDavid Wu #else 436f0a52e9SDavid Wu struct dw_eth_dev dw; 446f0a52e9SDavid Wu #endif 456f0a52e9SDavid Wu }; 466f0a52e9SDavid Wu 470125bcf0SSjoerd Simons /* 480125bcf0SSjoerd Simons * Platform data for the gmac 490125bcf0SSjoerd Simons * 500125bcf0SSjoerd Simons * dw_eth_pdata: Required platform data for designware driver (must be first) 510125bcf0SSjoerd Simons */ 520125bcf0SSjoerd Simons struct gmac_rockchip_platdata { 536f0a52e9SDavid Wu #ifndef CONFIG_DWC_ETH_QOS 540125bcf0SSjoerd Simons struct dw_eth_pdata dw_eth_pdata; 556f0a52e9SDavid Wu #else 566f0a52e9SDavid Wu struct eth_pdata eth_pdata; 576f0a52e9SDavid Wu #endif 580a33ce65SDavid Wu bool clock_input; 590125bcf0SSjoerd Simons int tx_delay; 600125bcf0SSjoerd Simons int rx_delay; 61*33a014bdSDavid Wu int bus_id; 620125bcf0SSjoerd Simons }; 630125bcf0SSjoerd Simons 641f08aa1cSPhilipp Tomsich struct rk_gmac_ops { 656f0a52e9SDavid Wu #ifdef CONFIG_DWC_ETH_QOS 666f0a52e9SDavid Wu const struct eqos_config config; 676f0a52e9SDavid Wu #endif 686f0a52e9SDavid Wu int (*fix_mac_speed)(struct rockchip_eth_dev *dev); 690a33ce65SDavid Wu void (*set_to_rmii)(struct gmac_rockchip_platdata *pdata); 701f08aa1cSPhilipp Tomsich void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata); 711f08aa1cSPhilipp Tomsich }; 721f08aa1cSPhilipp Tomsich 73befcb627SDavid Wu #ifdef CONFIG_DWC_ETH_QOS 74befcb627SDavid Wu static const struct eqos_config eqos_rockchip_config = { 75befcb627SDavid Wu .reg_access_always_ok = false, 76befcb627SDavid Wu .mdio_wait = 10000, 77befcb627SDavid Wu .swr_wait = 200, 78befcb627SDavid Wu .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_NOT_ENABLED, 79befcb627SDavid Wu .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_100_150, 80befcb627SDavid Wu .ops = &eqos_rockchip_ops, 81befcb627SDavid Wu }; 82befcb627SDavid Wu #endif 83befcb627SDavid Wu 841eb9d064SDavid Wu void gmac_set_rgmii(struct udevice *dev, u32 tx_delay, u32 rx_delay) 851eb9d064SDavid Wu { 861eb9d064SDavid Wu struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); 871eb9d064SDavid Wu struct rk_gmac_ops *ops = 881eb9d064SDavid Wu (struct rk_gmac_ops *)dev_get_driver_data(dev); 891eb9d064SDavid Wu 901eb9d064SDavid Wu pdata->tx_delay = tx_delay; 911eb9d064SDavid Wu pdata->rx_delay = rx_delay; 921eb9d064SDavid Wu 931eb9d064SDavid Wu ops->set_to_rgmii(pdata); 941eb9d064SDavid Wu } 951f08aa1cSPhilipp Tomsich 960125bcf0SSjoerd Simons static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) 970125bcf0SSjoerd Simons { 980125bcf0SSjoerd Simons struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); 990a33ce65SDavid Wu const char *string; 1000a33ce65SDavid Wu 1010a33ce65SDavid Wu string = dev_read_string(dev, "clock_in_out"); 1020a33ce65SDavid Wu if (!strcmp(string, "input")) 1030a33ce65SDavid Wu pdata->clock_input = true; 1040a33ce65SDavid Wu else 1050a33ce65SDavid Wu pdata->clock_input = false; 1060125bcf0SSjoerd Simons 1071f08aa1cSPhilipp Tomsich /* Check the new naming-style first... */ 1087ad326a9SPhilipp Tomsich pdata->tx_delay = dev_read_u32_default(dev, "tx_delay", -ENOENT); 1097ad326a9SPhilipp Tomsich pdata->rx_delay = dev_read_u32_default(dev, "rx_delay", -ENOENT); 1101f08aa1cSPhilipp Tomsich 1111f08aa1cSPhilipp Tomsich /* ... and fall back to the old naming style or default, if necessary */ 1121f08aa1cSPhilipp Tomsich if (pdata->tx_delay == -ENOENT) 1137ad326a9SPhilipp Tomsich pdata->tx_delay = dev_read_u32_default(dev, "tx-delay", 0x30); 1141f08aa1cSPhilipp Tomsich if (pdata->rx_delay == -ENOENT) 1157ad326a9SPhilipp Tomsich pdata->rx_delay = dev_read_u32_default(dev, "rx-delay", 0x10); 1160125bcf0SSjoerd Simons 1176f0a52e9SDavid Wu #ifdef CONFIG_DWC_ETH_QOS 1186f0a52e9SDavid Wu return 0; 1196f0a52e9SDavid Wu #else 1200125bcf0SSjoerd Simons return designware_eth_ofdata_to_platdata(dev); 1216f0a52e9SDavid Wu #endif 1220125bcf0SSjoerd Simons } 1230125bcf0SSjoerd Simons 1246f0a52e9SDavid Wu #ifndef CONFIG_DWC_ETH_QOS 1256f0a52e9SDavid Wu static int px30_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) 12618ae91c8SDavid Wu { 1276f0a52e9SDavid Wu struct dw_eth_dev *priv = &dev->dw; 12818ae91c8SDavid Wu struct px30_grf *grf; 12918ae91c8SDavid Wu struct clk clk_speed; 13018ae91c8SDavid Wu int speed, ret; 13118ae91c8SDavid Wu enum { 13218ae91c8SDavid Wu PX30_GMAC_SPEED_SHIFT = 0x2, 13318ae91c8SDavid Wu PX30_GMAC_SPEED_MASK = BIT(2), 13418ae91c8SDavid Wu PX30_GMAC_SPEED_10M = 0, 13518ae91c8SDavid Wu PX30_GMAC_SPEED_100M = BIT(2), 13618ae91c8SDavid Wu }; 13718ae91c8SDavid Wu 13818ae91c8SDavid Wu ret = clk_get_by_name(priv->phydev->dev, "clk_mac_speed", 13918ae91c8SDavid Wu &clk_speed); 14018ae91c8SDavid Wu if (ret) 14118ae91c8SDavid Wu return ret; 14218ae91c8SDavid Wu 14318ae91c8SDavid Wu switch (priv->phydev->speed) { 14418ae91c8SDavid Wu case 10: 14518ae91c8SDavid Wu speed = PX30_GMAC_SPEED_10M; 14618ae91c8SDavid Wu ret = clk_set_rate(&clk_speed, 2500000); 14718ae91c8SDavid Wu if (ret) 14818ae91c8SDavid Wu return ret; 14918ae91c8SDavid Wu break; 15018ae91c8SDavid Wu case 100: 15118ae91c8SDavid Wu speed = PX30_GMAC_SPEED_100M; 15218ae91c8SDavid Wu ret = clk_set_rate(&clk_speed, 25000000); 15318ae91c8SDavid Wu if (ret) 15418ae91c8SDavid Wu return ret; 15518ae91c8SDavid Wu break; 15618ae91c8SDavid Wu default: 15718ae91c8SDavid Wu debug("Unknown phy speed: %d\n", priv->phydev->speed); 15818ae91c8SDavid Wu return -EINVAL; 15918ae91c8SDavid Wu } 16018ae91c8SDavid Wu 16118ae91c8SDavid Wu grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 16218ae91c8SDavid Wu rk_clrsetreg(&grf->mac_con1, PX30_GMAC_SPEED_MASK, speed); 16318ae91c8SDavid Wu 16418ae91c8SDavid Wu return 0; 16518ae91c8SDavid Wu } 16618ae91c8SDavid Wu 1676f0a52e9SDavid Wu static int rk1808_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) 168ff86648dSDavid Wu { 1696f0a52e9SDavid Wu struct dw_eth_dev *priv = &dev->dw; 170ff86648dSDavid Wu struct clk clk_speed; 171ff86648dSDavid Wu int ret; 172ff86648dSDavid Wu 173ff86648dSDavid Wu ret = clk_get_by_name(priv->phydev->dev, "clk_mac_speed", 174ff86648dSDavid Wu &clk_speed); 175ff86648dSDavid Wu if (ret) 176ff86648dSDavid Wu return ret; 177ff86648dSDavid Wu 178ff86648dSDavid Wu switch (priv->phydev->speed) { 179ff86648dSDavid Wu case 10: 180ff86648dSDavid Wu ret = clk_set_rate(&clk_speed, 2500000); 181ff86648dSDavid Wu if (ret) 182ff86648dSDavid Wu return ret; 183ff86648dSDavid Wu break; 184ff86648dSDavid Wu case 100: 185ff86648dSDavid Wu ret = clk_set_rate(&clk_speed, 25000000); 186ff86648dSDavid Wu if (ret) 187ff86648dSDavid Wu return ret; 188ff86648dSDavid Wu break; 189ff86648dSDavid Wu case 1000: 190ff86648dSDavid Wu ret = clk_set_rate(&clk_speed, 125000000); 191ff86648dSDavid Wu if (ret) 192ff86648dSDavid Wu return ret; 193ff86648dSDavid Wu break; 194ff86648dSDavid Wu default: 195ff86648dSDavid Wu debug("Unknown phy speed: %d\n", priv->phydev->speed); 196ff86648dSDavid Wu return -EINVAL; 197ff86648dSDavid Wu } 198ff86648dSDavid Wu 199ff86648dSDavid Wu return 0; 200ff86648dSDavid Wu } 201ff86648dSDavid Wu 2026f0a52e9SDavid Wu static int rk3228_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) 203af166ffaSDavid Wu { 2046f0a52e9SDavid Wu struct dw_eth_dev *priv = &dev->dw; 205af166ffaSDavid Wu struct rk322x_grf *grf; 206af166ffaSDavid Wu int clk; 207af166ffaSDavid Wu enum { 208af166ffaSDavid Wu RK3228_GMAC_CLK_SEL_SHIFT = 8, 209af166ffaSDavid Wu RK3228_GMAC_CLK_SEL_MASK = GENMASK(9, 8), 210af166ffaSDavid Wu RK3228_GMAC_CLK_SEL_125M = 0 << 8, 211af166ffaSDavid Wu RK3228_GMAC_CLK_SEL_25M = 3 << 8, 212af166ffaSDavid Wu RK3228_GMAC_CLK_SEL_2_5M = 2 << 8, 213af166ffaSDavid Wu }; 214af166ffaSDavid Wu 215af166ffaSDavid Wu switch (priv->phydev->speed) { 216af166ffaSDavid Wu case 10: 217af166ffaSDavid Wu clk = RK3228_GMAC_CLK_SEL_2_5M; 218af166ffaSDavid Wu break; 219af166ffaSDavid Wu case 100: 220af166ffaSDavid Wu clk = RK3228_GMAC_CLK_SEL_25M; 221af166ffaSDavid Wu break; 222af166ffaSDavid Wu case 1000: 223af166ffaSDavid Wu clk = RK3228_GMAC_CLK_SEL_125M; 224af166ffaSDavid Wu break; 225af166ffaSDavid Wu default: 226af166ffaSDavid Wu debug("Unknown phy speed: %d\n", priv->phydev->speed); 227af166ffaSDavid Wu return -EINVAL; 228af166ffaSDavid Wu } 229af166ffaSDavid Wu 230af166ffaSDavid Wu grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 231af166ffaSDavid Wu rk_clrsetreg(&grf->mac_con[1], RK3228_GMAC_CLK_SEL_MASK, clk); 232af166ffaSDavid Wu 233af166ffaSDavid Wu return 0; 234af166ffaSDavid Wu } 235af166ffaSDavid Wu 2366f0a52e9SDavid Wu static int rk3288_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) 2370125bcf0SSjoerd Simons { 2386f0a52e9SDavid Wu struct dw_eth_dev *priv = &dev->dw; 2390125bcf0SSjoerd Simons struct rk3288_grf *grf; 2400125bcf0SSjoerd Simons int clk; 2410125bcf0SSjoerd Simons 2420125bcf0SSjoerd Simons switch (priv->phydev->speed) { 2430125bcf0SSjoerd Simons case 10: 2441f08aa1cSPhilipp Tomsich clk = RK3288_GMAC_CLK_SEL_2_5M; 2450125bcf0SSjoerd Simons break; 2460125bcf0SSjoerd Simons case 100: 2471f08aa1cSPhilipp Tomsich clk = RK3288_GMAC_CLK_SEL_25M; 2480125bcf0SSjoerd Simons break; 2490125bcf0SSjoerd Simons case 1000: 2501f08aa1cSPhilipp Tomsich clk = RK3288_GMAC_CLK_SEL_125M; 2510125bcf0SSjoerd Simons break; 2520125bcf0SSjoerd Simons default: 2530125bcf0SSjoerd Simons debug("Unknown phy speed: %d\n", priv->phydev->speed); 2540125bcf0SSjoerd Simons return -EINVAL; 2550125bcf0SSjoerd Simons } 2560125bcf0SSjoerd Simons 2570125bcf0SSjoerd Simons grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 2581f08aa1cSPhilipp Tomsich rk_clrsetreg(&grf->soc_con1, RK3288_GMAC_CLK_SEL_MASK, clk); 2590125bcf0SSjoerd Simons 2600125bcf0SSjoerd Simons return 0; 2610125bcf0SSjoerd Simons } 2620125bcf0SSjoerd Simons 2636f0a52e9SDavid Wu static int rk3308_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) 26423adb58fSDavid Wu { 2656f0a52e9SDavid Wu struct dw_eth_dev *priv = &dev->dw; 26623adb58fSDavid Wu struct rk3308_grf *grf; 26723adb58fSDavid Wu struct clk clk_speed; 26823adb58fSDavid Wu int speed, ret; 26923adb58fSDavid Wu enum { 27023adb58fSDavid Wu RK3308_GMAC_SPEED_SHIFT = 0x0, 27123adb58fSDavid Wu RK3308_GMAC_SPEED_MASK = BIT(0), 27223adb58fSDavid Wu RK3308_GMAC_SPEED_10M = 0, 27323adb58fSDavid Wu RK3308_GMAC_SPEED_100M = BIT(0), 27423adb58fSDavid Wu }; 27523adb58fSDavid Wu 27623adb58fSDavid Wu ret = clk_get_by_name(priv->phydev->dev, "clk_mac_speed", 27723adb58fSDavid Wu &clk_speed); 27823adb58fSDavid Wu if (ret) 27923adb58fSDavid Wu return ret; 28023adb58fSDavid Wu 28123adb58fSDavid Wu switch (priv->phydev->speed) { 28223adb58fSDavid Wu case 10: 28323adb58fSDavid Wu speed = RK3308_GMAC_SPEED_10M; 28423adb58fSDavid Wu ret = clk_set_rate(&clk_speed, 2500000); 28523adb58fSDavid Wu if (ret) 28623adb58fSDavid Wu return ret; 28723adb58fSDavid Wu break; 28823adb58fSDavid Wu case 100: 28923adb58fSDavid Wu speed = RK3308_GMAC_SPEED_100M; 29023adb58fSDavid Wu ret = clk_set_rate(&clk_speed, 25000000); 29123adb58fSDavid Wu if (ret) 29223adb58fSDavid Wu return ret; 29323adb58fSDavid Wu break; 29423adb58fSDavid Wu default: 29523adb58fSDavid Wu debug("Unknown phy speed: %d\n", priv->phydev->speed); 29623adb58fSDavid Wu return -EINVAL; 29723adb58fSDavid Wu } 29823adb58fSDavid Wu 29923adb58fSDavid Wu grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 30023adb58fSDavid Wu rk_clrsetreg(&grf->mac_con0, RK3308_GMAC_SPEED_MASK, speed); 30123adb58fSDavid Wu 30223adb58fSDavid Wu return 0; 30323adb58fSDavid Wu } 30423adb58fSDavid Wu 3056f0a52e9SDavid Wu static int rk3328_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) 306c36b26c0SDavid Wu { 3076f0a52e9SDavid Wu struct dw_eth_dev *priv = &dev->dw; 308c36b26c0SDavid Wu struct rk3328_grf_regs *grf; 309c36b26c0SDavid Wu int clk; 310c36b26c0SDavid Wu enum { 311c36b26c0SDavid Wu RK3328_GMAC_CLK_SEL_SHIFT = 11, 312c36b26c0SDavid Wu RK3328_GMAC_CLK_SEL_MASK = GENMASK(12, 11), 313c36b26c0SDavid Wu RK3328_GMAC_CLK_SEL_125M = 0 << 11, 314c36b26c0SDavid Wu RK3328_GMAC_CLK_SEL_25M = 3 << 11, 315c36b26c0SDavid Wu RK3328_GMAC_CLK_SEL_2_5M = 2 << 11, 316c36b26c0SDavid Wu }; 317c36b26c0SDavid Wu 318c36b26c0SDavid Wu switch (priv->phydev->speed) { 319c36b26c0SDavid Wu case 10: 320c36b26c0SDavid Wu clk = RK3328_GMAC_CLK_SEL_2_5M; 321c36b26c0SDavid Wu break; 322c36b26c0SDavid Wu case 100: 323c36b26c0SDavid Wu clk = RK3328_GMAC_CLK_SEL_25M; 324c36b26c0SDavid Wu break; 325c36b26c0SDavid Wu case 1000: 326c36b26c0SDavid Wu clk = RK3328_GMAC_CLK_SEL_125M; 327c36b26c0SDavid Wu break; 328c36b26c0SDavid Wu default: 329c36b26c0SDavid Wu debug("Unknown phy speed: %d\n", priv->phydev->speed); 330c36b26c0SDavid Wu return -EINVAL; 331c36b26c0SDavid Wu } 332c36b26c0SDavid Wu 333c36b26c0SDavid Wu grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 334c36b26c0SDavid Wu rk_clrsetreg(&grf->mac_con[1], RK3328_GMAC_CLK_SEL_MASK, clk); 335c36b26c0SDavid Wu 336c36b26c0SDavid Wu return 0; 337c36b26c0SDavid Wu } 338c36b26c0SDavid Wu 3396f0a52e9SDavid Wu static int rk3368_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) 340793f2fd2SPhilipp Tomsich { 3416f0a52e9SDavid Wu struct dw_eth_dev *priv = &dev->dw; 342793f2fd2SPhilipp Tomsich struct rk3368_grf *grf; 343793f2fd2SPhilipp Tomsich int clk; 344793f2fd2SPhilipp Tomsich enum { 345793f2fd2SPhilipp Tomsich RK3368_GMAC_CLK_SEL_2_5M = 2 << 4, 346793f2fd2SPhilipp Tomsich RK3368_GMAC_CLK_SEL_25M = 3 << 4, 347793f2fd2SPhilipp Tomsich RK3368_GMAC_CLK_SEL_125M = 0 << 4, 348793f2fd2SPhilipp Tomsich RK3368_GMAC_CLK_SEL_MASK = GENMASK(5, 4), 349793f2fd2SPhilipp Tomsich }; 350793f2fd2SPhilipp Tomsich 351793f2fd2SPhilipp Tomsich switch (priv->phydev->speed) { 352793f2fd2SPhilipp Tomsich case 10: 353793f2fd2SPhilipp Tomsich clk = RK3368_GMAC_CLK_SEL_2_5M; 354793f2fd2SPhilipp Tomsich break; 355793f2fd2SPhilipp Tomsich case 100: 356793f2fd2SPhilipp Tomsich clk = RK3368_GMAC_CLK_SEL_25M; 357793f2fd2SPhilipp Tomsich break; 358793f2fd2SPhilipp Tomsich case 1000: 359793f2fd2SPhilipp Tomsich clk = RK3368_GMAC_CLK_SEL_125M; 360793f2fd2SPhilipp Tomsich break; 361793f2fd2SPhilipp Tomsich default: 362793f2fd2SPhilipp Tomsich debug("Unknown phy speed: %d\n", priv->phydev->speed); 363793f2fd2SPhilipp Tomsich return -EINVAL; 364793f2fd2SPhilipp Tomsich } 365793f2fd2SPhilipp Tomsich 366793f2fd2SPhilipp Tomsich grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 367793f2fd2SPhilipp Tomsich rk_clrsetreg(&grf->soc_con15, RK3368_GMAC_CLK_SEL_MASK, clk); 368793f2fd2SPhilipp Tomsich 369793f2fd2SPhilipp Tomsich return 0; 370793f2fd2SPhilipp Tomsich } 371793f2fd2SPhilipp Tomsich 3726f0a52e9SDavid Wu static int rk3399_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) 3731f08aa1cSPhilipp Tomsich { 3746f0a52e9SDavid Wu struct dw_eth_dev *priv = &dev->dw; 3751f08aa1cSPhilipp Tomsich struct rk3399_grf_regs *grf; 3761f08aa1cSPhilipp Tomsich int clk; 3771f08aa1cSPhilipp Tomsich 3781f08aa1cSPhilipp Tomsich switch (priv->phydev->speed) { 3791f08aa1cSPhilipp Tomsich case 10: 3801f08aa1cSPhilipp Tomsich clk = RK3399_GMAC_CLK_SEL_2_5M; 3811f08aa1cSPhilipp Tomsich break; 3821f08aa1cSPhilipp Tomsich case 100: 3831f08aa1cSPhilipp Tomsich clk = RK3399_GMAC_CLK_SEL_25M; 3841f08aa1cSPhilipp Tomsich break; 3851f08aa1cSPhilipp Tomsich case 1000: 3861f08aa1cSPhilipp Tomsich clk = RK3399_GMAC_CLK_SEL_125M; 3871f08aa1cSPhilipp Tomsich break; 3881f08aa1cSPhilipp Tomsich default: 3891f08aa1cSPhilipp Tomsich debug("Unknown phy speed: %d\n", priv->phydev->speed); 3901f08aa1cSPhilipp Tomsich return -EINVAL; 3911f08aa1cSPhilipp Tomsich } 3921f08aa1cSPhilipp Tomsich 3931f08aa1cSPhilipp Tomsich grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 3941f08aa1cSPhilipp Tomsich rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_CLK_SEL_MASK, clk); 3951f08aa1cSPhilipp Tomsich 3961f08aa1cSPhilipp Tomsich return 0; 3971f08aa1cSPhilipp Tomsich } 3981f08aa1cSPhilipp Tomsich 3996f0a52e9SDavid Wu static int rv1108_set_rmii_speed(struct rockchip_eth_dev *dev) 4000a33ce65SDavid Wu { 4016f0a52e9SDavid Wu struct dw_eth_dev *priv = &dev->dw; 4020a33ce65SDavid Wu struct rv1108_grf *grf; 4030a33ce65SDavid Wu int clk, speed; 4040a33ce65SDavid Wu enum { 4050a33ce65SDavid Wu RV1108_GMAC_SPEED_MASK = BIT(2), 4060a33ce65SDavid Wu RV1108_GMAC_SPEED_10M = 0 << 2, 4070a33ce65SDavid Wu RV1108_GMAC_SPEED_100M = 1 << 2, 4080a33ce65SDavid Wu RV1108_GMAC_CLK_SEL_MASK = BIT(7), 4090a33ce65SDavid Wu RV1108_GMAC_CLK_SEL_2_5M = 0 << 7, 4100a33ce65SDavid Wu RV1108_GMAC_CLK_SEL_25M = 1 << 7, 4110a33ce65SDavid Wu }; 4120a33ce65SDavid Wu 4130a33ce65SDavid Wu switch (priv->phydev->speed) { 4140a33ce65SDavid Wu case 10: 4150a33ce65SDavid Wu clk = RV1108_GMAC_CLK_SEL_2_5M; 4160a33ce65SDavid Wu speed = RV1108_GMAC_SPEED_10M; 4170a33ce65SDavid Wu break; 4180a33ce65SDavid Wu case 100: 4190a33ce65SDavid Wu clk = RV1108_GMAC_CLK_SEL_25M; 4200a33ce65SDavid Wu speed = RV1108_GMAC_SPEED_100M; 4210a33ce65SDavid Wu break; 4220a33ce65SDavid Wu default: 4230a33ce65SDavid Wu debug("Unknown phy speed: %d\n", priv->phydev->speed); 4240a33ce65SDavid Wu return -EINVAL; 4250a33ce65SDavid Wu } 4260a33ce65SDavid Wu 4270a33ce65SDavid Wu grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 4280a33ce65SDavid Wu rk_clrsetreg(&grf->gmac_con0, 4290a33ce65SDavid Wu RV1108_GMAC_CLK_SEL_MASK | RV1108_GMAC_SPEED_MASK, 4300a33ce65SDavid Wu clk | speed); 4310a33ce65SDavid Wu 4320a33ce65SDavid Wu return 0; 4330a33ce65SDavid Wu } 434dcfb333aSDavid Wu #else 435dcfb333aSDavid Wu static int rv1126_set_rgmii_speed(struct rockchip_eth_dev *dev) 436dcfb333aSDavid Wu { 437dcfb333aSDavid Wu struct eqos_priv *priv = &dev->eqos; 438dcfb333aSDavid Wu struct clk clk_speed; 439dcfb333aSDavid Wu int ret; 440dcfb333aSDavid Wu 441dcfb333aSDavid Wu ret = clk_get_by_name(priv->phy->dev, "clk_mac_speed", 442dcfb333aSDavid Wu &clk_speed); 443dcfb333aSDavid Wu if (ret) { 444*33a014bdSDavid Wu printf("%s can't get clk_mac_speed clock (ret=%d):\n", 445*33a014bdSDavid Wu __func__, ret); 446dcfb333aSDavid Wu return ret; 447dcfb333aSDavid Wu } 448dcfb333aSDavid Wu 449dcfb333aSDavid Wu switch ( priv->phy->speed) { 450dcfb333aSDavid Wu case 10: 451dcfb333aSDavid Wu ret = clk_set_rate(&clk_speed, 2500000); 452dcfb333aSDavid Wu if (ret) 453dcfb333aSDavid Wu return ret; 454dcfb333aSDavid Wu break; 455dcfb333aSDavid Wu case 100: 456dcfb333aSDavid Wu ret = clk_set_rate(&clk_speed, 25000000); 457dcfb333aSDavid Wu if (ret) 458dcfb333aSDavid Wu return ret; 459dcfb333aSDavid Wu break; 460dcfb333aSDavid Wu case 1000: 461dcfb333aSDavid Wu ret = clk_set_rate(&clk_speed, 125000000); 462dcfb333aSDavid Wu if (ret) 463dcfb333aSDavid Wu return ret; 464dcfb333aSDavid Wu break; 465dcfb333aSDavid Wu default: 466dcfb333aSDavid Wu debug("Unknown phy speed: %d\n", priv->phy->speed); 467dcfb333aSDavid Wu return -EINVAL; 468dcfb333aSDavid Wu } 469dcfb333aSDavid Wu 470dcfb333aSDavid Wu return 0; 471dcfb333aSDavid Wu } 4726f0a52e9SDavid Wu #endif 4730a33ce65SDavid Wu 4746f0a52e9SDavid Wu #ifndef CONFIG_DWC_ETH_QOS 47518ae91c8SDavid Wu static void px30_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata) 47618ae91c8SDavid Wu { 47718ae91c8SDavid Wu struct px30_grf *grf; 47818ae91c8SDavid Wu enum { 47918ae91c8SDavid Wu px30_GMAC_PHY_INTF_SEL_SHIFT = 4, 48018ae91c8SDavid Wu px30_GMAC_PHY_INTF_SEL_MASK = GENMASK(4, 6), 48118ae91c8SDavid Wu px30_GMAC_PHY_INTF_SEL_RMII = BIT(6), 48218ae91c8SDavid Wu }; 48318ae91c8SDavid Wu 48418ae91c8SDavid Wu grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 48518ae91c8SDavid Wu 48618ae91c8SDavid Wu rk_clrsetreg(&grf->mac_con1, 48718ae91c8SDavid Wu px30_GMAC_PHY_INTF_SEL_MASK, 48818ae91c8SDavid Wu px30_GMAC_PHY_INTF_SEL_RMII); 48918ae91c8SDavid Wu } 49018ae91c8SDavid Wu 491ff86648dSDavid Wu static void rk1808_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) 492ff86648dSDavid Wu { 493ff86648dSDavid Wu struct rk1808_grf *grf; 494ff86648dSDavid Wu enum { 495ff86648dSDavid Wu RK1808_GMAC_PHY_INTF_SEL_SHIFT = 4, 496ff86648dSDavid Wu RK1808_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4), 497ff86648dSDavid Wu RK1808_GMAC_PHY_INTF_SEL_RGMII = BIT(4), 498ff86648dSDavid Wu 499ff86648dSDavid Wu RK1808_RXCLK_DLY_ENA_GMAC_MASK = BIT(1), 500ff86648dSDavid Wu RK1808_RXCLK_DLY_ENA_GMAC_DISABLE = 0, 501ff86648dSDavid Wu RK1808_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(1), 502ff86648dSDavid Wu 503ff86648dSDavid Wu RK1808_TXCLK_DLY_ENA_GMAC_MASK = BIT(0), 504ff86648dSDavid Wu RK1808_TXCLK_DLY_ENA_GMAC_DISABLE = 0, 505ff86648dSDavid Wu RK1808_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(0), 506ff86648dSDavid Wu }; 507ff86648dSDavid Wu enum { 508ff86648dSDavid Wu RK1808_CLK_RX_DL_CFG_GMAC_SHIFT = 0x8, 509ff86648dSDavid Wu RK1808_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(15, 7), 510ff86648dSDavid Wu 511ff86648dSDavid Wu RK1808_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0, 512ff86648dSDavid Wu RK1808_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(7, 0), 513ff86648dSDavid Wu }; 514ff86648dSDavid Wu 515ff86648dSDavid Wu grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 516ff86648dSDavid Wu rk_clrsetreg(&grf->mac_con1, 517ff86648dSDavid Wu RK1808_GMAC_PHY_INTF_SEL_MASK | 518ff86648dSDavid Wu RK1808_RXCLK_DLY_ENA_GMAC_MASK | 519ff86648dSDavid Wu RK1808_TXCLK_DLY_ENA_GMAC_MASK, 520ff86648dSDavid Wu RK1808_GMAC_PHY_INTF_SEL_RGMII | 521ff86648dSDavid Wu RK1808_RXCLK_DLY_ENA_GMAC_ENABLE | 522ff86648dSDavid Wu RK1808_TXCLK_DLY_ENA_GMAC_ENABLE); 523ff86648dSDavid Wu 524ff86648dSDavid Wu rk_clrsetreg(&grf->mac_con0, 525ff86648dSDavid Wu RK1808_CLK_RX_DL_CFG_GMAC_MASK | 526ff86648dSDavid Wu RK1808_CLK_TX_DL_CFG_GMAC_MASK, 527ff86648dSDavid Wu pdata->rx_delay << RK1808_CLK_RX_DL_CFG_GMAC_SHIFT | 528ff86648dSDavid Wu pdata->tx_delay << RK1808_CLK_TX_DL_CFG_GMAC_SHIFT); 529ff86648dSDavid Wu } 530ff86648dSDavid Wu 531af166ffaSDavid Wu static void rk3228_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) 532af166ffaSDavid Wu { 533af166ffaSDavid Wu struct rk322x_grf *grf; 534af166ffaSDavid Wu enum { 535af166ffaSDavid Wu RK3228_RMII_MODE_SHIFT = 10, 536af166ffaSDavid Wu RK3228_RMII_MODE_MASK = BIT(10), 537af166ffaSDavid Wu 538af166ffaSDavid Wu RK3228_GMAC_PHY_INTF_SEL_SHIFT = 4, 539af166ffaSDavid Wu RK3228_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4), 540af166ffaSDavid Wu RK3228_GMAC_PHY_INTF_SEL_RGMII = BIT(4), 541af166ffaSDavid Wu 542af166ffaSDavid Wu RK3228_RXCLK_DLY_ENA_GMAC_MASK = BIT(1), 543af166ffaSDavid Wu RK3228_RXCLK_DLY_ENA_GMAC_DISABLE = 0, 544af166ffaSDavid Wu RK3228_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(1), 545af166ffaSDavid Wu 546af166ffaSDavid Wu RK3228_TXCLK_DLY_ENA_GMAC_MASK = BIT(0), 547af166ffaSDavid Wu RK3228_TXCLK_DLY_ENA_GMAC_DISABLE = 0, 548af166ffaSDavid Wu RK3228_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(0), 549af166ffaSDavid Wu }; 550af166ffaSDavid Wu enum { 551af166ffaSDavid Wu RK3228_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7, 552af166ffaSDavid Wu RK3228_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7), 553af166ffaSDavid Wu 554af166ffaSDavid Wu RK3228_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0, 555af166ffaSDavid Wu RK3228_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0), 556af166ffaSDavid Wu }; 557af166ffaSDavid Wu 558af166ffaSDavid Wu grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 559af166ffaSDavid Wu rk_clrsetreg(&grf->mac_con[1], 560af166ffaSDavid Wu RK3228_RMII_MODE_MASK | 561af166ffaSDavid Wu RK3228_GMAC_PHY_INTF_SEL_MASK | 562af166ffaSDavid Wu RK3228_RXCLK_DLY_ENA_GMAC_MASK | 563af166ffaSDavid Wu RK3228_TXCLK_DLY_ENA_GMAC_MASK, 564af166ffaSDavid Wu RK3228_GMAC_PHY_INTF_SEL_RGMII | 565af166ffaSDavid Wu RK3228_RXCLK_DLY_ENA_GMAC_ENABLE | 566af166ffaSDavid Wu RK3228_TXCLK_DLY_ENA_GMAC_ENABLE); 567af166ffaSDavid Wu 568af166ffaSDavid Wu rk_clrsetreg(&grf->mac_con[0], 569af166ffaSDavid Wu RK3228_CLK_RX_DL_CFG_GMAC_MASK | 570af166ffaSDavid Wu RK3228_CLK_TX_DL_CFG_GMAC_MASK, 571af166ffaSDavid Wu pdata->rx_delay << RK3228_CLK_RX_DL_CFG_GMAC_SHIFT | 572af166ffaSDavid Wu pdata->tx_delay << RK3228_CLK_TX_DL_CFG_GMAC_SHIFT); 573af166ffaSDavid Wu } 574af166ffaSDavid Wu 5751f08aa1cSPhilipp Tomsich static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) 5761f08aa1cSPhilipp Tomsich { 5771f08aa1cSPhilipp Tomsich struct rk3288_grf *grf; 5781f08aa1cSPhilipp Tomsich 5791f08aa1cSPhilipp Tomsich grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 5801f08aa1cSPhilipp Tomsich rk_clrsetreg(&grf->soc_con1, 5811f08aa1cSPhilipp Tomsich RK3288_RMII_MODE_MASK | RK3288_GMAC_PHY_INTF_SEL_MASK, 5821f08aa1cSPhilipp Tomsich RK3288_GMAC_PHY_INTF_SEL_RGMII); 5831f08aa1cSPhilipp Tomsich 5841f08aa1cSPhilipp Tomsich rk_clrsetreg(&grf->soc_con3, 5851f08aa1cSPhilipp Tomsich RK3288_RXCLK_DLY_ENA_GMAC_MASK | 5861f08aa1cSPhilipp Tomsich RK3288_TXCLK_DLY_ENA_GMAC_MASK | 5871f08aa1cSPhilipp Tomsich RK3288_CLK_RX_DL_CFG_GMAC_MASK | 5881f08aa1cSPhilipp Tomsich RK3288_CLK_TX_DL_CFG_GMAC_MASK, 5891f08aa1cSPhilipp Tomsich RK3288_RXCLK_DLY_ENA_GMAC_ENABLE | 5901f08aa1cSPhilipp Tomsich RK3288_TXCLK_DLY_ENA_GMAC_ENABLE | 5911f08aa1cSPhilipp Tomsich pdata->rx_delay << RK3288_CLK_RX_DL_CFG_GMAC_SHIFT | 5921f08aa1cSPhilipp Tomsich pdata->tx_delay << RK3288_CLK_TX_DL_CFG_GMAC_SHIFT); 5931f08aa1cSPhilipp Tomsich } 5941f08aa1cSPhilipp Tomsich 59523adb58fSDavid Wu static void rk3308_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata) 59623adb58fSDavid Wu { 59723adb58fSDavid Wu struct rk3308_grf *grf; 59823adb58fSDavid Wu enum { 59923adb58fSDavid Wu RK3308_GMAC_PHY_INTF_SEL_SHIFT = 2, 60023adb58fSDavid Wu RK3308_GMAC_PHY_INTF_SEL_MASK = GENMASK(4, 2), 60123adb58fSDavid Wu RK3308_GMAC_PHY_INTF_SEL_RMII = BIT(4), 60223adb58fSDavid Wu }; 60323adb58fSDavid Wu 60423adb58fSDavid Wu grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 60523adb58fSDavid Wu 60623adb58fSDavid Wu rk_clrsetreg(&grf->mac_con0, 60723adb58fSDavid Wu RK3308_GMAC_PHY_INTF_SEL_MASK, 60823adb58fSDavid Wu RK3308_GMAC_PHY_INTF_SEL_RMII); 60923adb58fSDavid Wu } 61023adb58fSDavid Wu 611c36b26c0SDavid Wu static void rk3328_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) 612c36b26c0SDavid Wu { 613c36b26c0SDavid Wu struct rk3328_grf_regs *grf; 614c36b26c0SDavid Wu enum { 615c36b26c0SDavid Wu RK3328_RMII_MODE_SHIFT = 9, 616c36b26c0SDavid Wu RK3328_RMII_MODE_MASK = BIT(9), 617c36b26c0SDavid Wu 618c36b26c0SDavid Wu RK3328_GMAC_PHY_INTF_SEL_SHIFT = 4, 619c36b26c0SDavid Wu RK3328_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4), 620c36b26c0SDavid Wu RK3328_GMAC_PHY_INTF_SEL_RGMII = BIT(4), 621c36b26c0SDavid Wu 622c36b26c0SDavid Wu RK3328_RXCLK_DLY_ENA_GMAC_MASK = BIT(1), 623c36b26c0SDavid Wu RK3328_RXCLK_DLY_ENA_GMAC_DISABLE = 0, 624c36b26c0SDavid Wu RK3328_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(1), 625c36b26c0SDavid Wu 626c36b26c0SDavid Wu RK3328_TXCLK_DLY_ENA_GMAC_MASK = BIT(0), 627c36b26c0SDavid Wu RK3328_TXCLK_DLY_ENA_GMAC_DISABLE = 0, 628c36b26c0SDavid Wu RK3328_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(0), 629c36b26c0SDavid Wu }; 630c36b26c0SDavid Wu enum { 631c36b26c0SDavid Wu RK3328_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7, 632c36b26c0SDavid Wu RK3328_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(13, 7), 633c36b26c0SDavid Wu 634c36b26c0SDavid Wu RK3328_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0, 635c36b26c0SDavid Wu RK3328_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0), 636c36b26c0SDavid Wu }; 637c36b26c0SDavid Wu 638c36b26c0SDavid Wu grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 639c36b26c0SDavid Wu rk_clrsetreg(&grf->mac_con[1], 640c36b26c0SDavid Wu RK3328_RMII_MODE_MASK | 641c36b26c0SDavid Wu RK3328_GMAC_PHY_INTF_SEL_MASK | 642c36b26c0SDavid Wu RK3328_RXCLK_DLY_ENA_GMAC_MASK | 643c36b26c0SDavid Wu RK3328_TXCLK_DLY_ENA_GMAC_MASK, 644c36b26c0SDavid Wu RK3328_GMAC_PHY_INTF_SEL_RGMII | 645c36b26c0SDavid Wu RK3328_RXCLK_DLY_ENA_GMAC_MASK | 646c36b26c0SDavid Wu RK3328_TXCLK_DLY_ENA_GMAC_ENABLE); 647c36b26c0SDavid Wu 648c36b26c0SDavid Wu rk_clrsetreg(&grf->mac_con[0], 649c36b26c0SDavid Wu RK3328_CLK_RX_DL_CFG_GMAC_MASK | 650c36b26c0SDavid Wu RK3328_CLK_TX_DL_CFG_GMAC_MASK, 651c36b26c0SDavid Wu pdata->rx_delay << RK3328_CLK_RX_DL_CFG_GMAC_SHIFT | 652c36b26c0SDavid Wu pdata->tx_delay << RK3328_CLK_TX_DL_CFG_GMAC_SHIFT); 653c36b26c0SDavid Wu } 654c36b26c0SDavid Wu 655793f2fd2SPhilipp Tomsich static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) 656793f2fd2SPhilipp Tomsich { 657793f2fd2SPhilipp Tomsich struct rk3368_grf *grf; 658793f2fd2SPhilipp Tomsich enum { 659793f2fd2SPhilipp Tomsich RK3368_GMAC_PHY_INTF_SEL_RGMII = 1 << 9, 660793f2fd2SPhilipp Tomsich RK3368_GMAC_PHY_INTF_SEL_MASK = GENMASK(11, 9), 661793f2fd2SPhilipp Tomsich RK3368_RMII_MODE_MASK = BIT(6), 662793f2fd2SPhilipp Tomsich RK3368_RMII_MODE = BIT(6), 663793f2fd2SPhilipp Tomsich }; 664793f2fd2SPhilipp Tomsich enum { 665793f2fd2SPhilipp Tomsich RK3368_RXCLK_DLY_ENA_GMAC_MASK = BIT(15), 666793f2fd2SPhilipp Tomsich RK3368_RXCLK_DLY_ENA_GMAC_DISABLE = 0, 667793f2fd2SPhilipp Tomsich RK3368_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(15), 668793f2fd2SPhilipp Tomsich RK3368_TXCLK_DLY_ENA_GMAC_MASK = BIT(7), 669793f2fd2SPhilipp Tomsich RK3368_TXCLK_DLY_ENA_GMAC_DISABLE = 0, 670793f2fd2SPhilipp Tomsich RK3368_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(7), 671793f2fd2SPhilipp Tomsich RK3368_CLK_RX_DL_CFG_GMAC_SHIFT = 8, 672793f2fd2SPhilipp Tomsich RK3368_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(14, 8), 673793f2fd2SPhilipp Tomsich RK3368_CLK_TX_DL_CFG_GMAC_SHIFT = 0, 674793f2fd2SPhilipp Tomsich RK3368_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0), 675793f2fd2SPhilipp Tomsich }; 676793f2fd2SPhilipp Tomsich 677793f2fd2SPhilipp Tomsich grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 678793f2fd2SPhilipp Tomsich rk_clrsetreg(&grf->soc_con15, 679793f2fd2SPhilipp Tomsich RK3368_RMII_MODE_MASK | RK3368_GMAC_PHY_INTF_SEL_MASK, 680793f2fd2SPhilipp Tomsich RK3368_GMAC_PHY_INTF_SEL_RGMII); 681793f2fd2SPhilipp Tomsich 682793f2fd2SPhilipp Tomsich rk_clrsetreg(&grf->soc_con16, 683793f2fd2SPhilipp Tomsich RK3368_RXCLK_DLY_ENA_GMAC_MASK | 684793f2fd2SPhilipp Tomsich RK3368_TXCLK_DLY_ENA_GMAC_MASK | 685793f2fd2SPhilipp Tomsich RK3368_CLK_RX_DL_CFG_GMAC_MASK | 686793f2fd2SPhilipp Tomsich RK3368_CLK_TX_DL_CFG_GMAC_MASK, 687793f2fd2SPhilipp Tomsich RK3368_RXCLK_DLY_ENA_GMAC_ENABLE | 688793f2fd2SPhilipp Tomsich RK3368_TXCLK_DLY_ENA_GMAC_ENABLE | 689793f2fd2SPhilipp Tomsich pdata->rx_delay << RK3368_CLK_RX_DL_CFG_GMAC_SHIFT | 690793f2fd2SPhilipp Tomsich pdata->tx_delay << RK3368_CLK_TX_DL_CFG_GMAC_SHIFT); 691793f2fd2SPhilipp Tomsich } 692793f2fd2SPhilipp Tomsich 6931f08aa1cSPhilipp Tomsich static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) 6941f08aa1cSPhilipp Tomsich { 6951f08aa1cSPhilipp Tomsich struct rk3399_grf_regs *grf; 6961f08aa1cSPhilipp Tomsich 6971f08aa1cSPhilipp Tomsich grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 6981f08aa1cSPhilipp Tomsich 6991f08aa1cSPhilipp Tomsich rk_clrsetreg(&grf->soc_con5, 7001f08aa1cSPhilipp Tomsich RK3399_GMAC_PHY_INTF_SEL_MASK, 7011f08aa1cSPhilipp Tomsich RK3399_GMAC_PHY_INTF_SEL_RGMII); 7021f08aa1cSPhilipp Tomsich 7031f08aa1cSPhilipp Tomsich rk_clrsetreg(&grf->soc_con6, 7041f08aa1cSPhilipp Tomsich RK3399_RXCLK_DLY_ENA_GMAC_MASK | 7051f08aa1cSPhilipp Tomsich RK3399_TXCLK_DLY_ENA_GMAC_MASK | 7061f08aa1cSPhilipp Tomsich RK3399_CLK_RX_DL_CFG_GMAC_MASK | 7071f08aa1cSPhilipp Tomsich RK3399_CLK_TX_DL_CFG_GMAC_MASK, 7081f08aa1cSPhilipp Tomsich RK3399_RXCLK_DLY_ENA_GMAC_ENABLE | 7091f08aa1cSPhilipp Tomsich RK3399_TXCLK_DLY_ENA_GMAC_ENABLE | 7101f08aa1cSPhilipp Tomsich pdata->rx_delay << RK3399_CLK_RX_DL_CFG_GMAC_SHIFT | 7111f08aa1cSPhilipp Tomsich pdata->tx_delay << RK3399_CLK_TX_DL_CFG_GMAC_SHIFT); 7121f08aa1cSPhilipp Tomsich } 7131f08aa1cSPhilipp Tomsich 7140a33ce65SDavid Wu static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata) 7150a33ce65SDavid Wu { 7160a33ce65SDavid Wu struct rv1108_grf *grf; 7170a33ce65SDavid Wu 7180a33ce65SDavid Wu enum { 7190a33ce65SDavid Wu RV1108_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4), 7200a33ce65SDavid Wu RV1108_GMAC_PHY_INTF_SEL_RMII = 4 << 4, 7210a33ce65SDavid Wu }; 7220a33ce65SDavid Wu 7230a33ce65SDavid Wu grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 7240a33ce65SDavid Wu rk_clrsetreg(&grf->gmac_con0, 7250a33ce65SDavid Wu RV1108_GMAC_PHY_INTF_SEL_MASK, 7260a33ce65SDavid Wu RV1108_GMAC_PHY_INTF_SEL_RMII); 7270a33ce65SDavid Wu } 728dcfb333aSDavid Wu #else 729*33a014bdSDavid Wu static void rk3568_set_to_rmii(struct gmac_rockchip_platdata *pdata) 730*33a014bdSDavid Wu { 731*33a014bdSDavid Wu struct rk3568_grf *grf; 732*33a014bdSDavid Wu void *con1; 733*33a014bdSDavid Wu 734*33a014bdSDavid Wu enum { 735*33a014bdSDavid Wu RK3568_GMAC_PHY_INTF_SEL_SHIFT = 4, 736*33a014bdSDavid Wu RK3568_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4), 737*33a014bdSDavid Wu RK3568_GMAC_PHY_INTF_SEL_RMII = BIT(6), 738*33a014bdSDavid Wu }; 739*33a014bdSDavid Wu 740*33a014bdSDavid Wu grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 741*33a014bdSDavid Wu 742*33a014bdSDavid Wu if (pdata->bus_id == 1) 743*33a014bdSDavid Wu con1 = &grf->mac1_con1; 744*33a014bdSDavid Wu else 745*33a014bdSDavid Wu con1 = &grf->mac0_con1; 746*33a014bdSDavid Wu 747*33a014bdSDavid Wu rk_clrsetreg(con1, 748*33a014bdSDavid Wu RK3568_GMAC_PHY_INTF_SEL_MASK, 749*33a014bdSDavid Wu RK3568_GMAC_PHY_INTF_SEL_RMII); 750*33a014bdSDavid Wu } 751*33a014bdSDavid Wu 752*33a014bdSDavid Wu static void rk3568_set_to_rgmii(struct gmac_rockchip_platdata *pdata) 753*33a014bdSDavid Wu { 754*33a014bdSDavid Wu struct rk3568_grf *grf; 755*33a014bdSDavid Wu void *con0, *con1; 756*33a014bdSDavid Wu 757*33a014bdSDavid Wu enum { 758*33a014bdSDavid Wu RK3568_GMAC_PHY_INTF_SEL_SHIFT = 4, 759*33a014bdSDavid Wu RK3568_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4), 760*33a014bdSDavid Wu RK3568_GMAC_PHY_INTF_SEL_RGMII = BIT(4), 761*33a014bdSDavid Wu 762*33a014bdSDavid Wu RK3568_RXCLK_DLY_ENA_GMAC_MASK = BIT(1), 763*33a014bdSDavid Wu RK3568_RXCLK_DLY_ENA_GMAC_DISABLE = 0, 764*33a014bdSDavid Wu RK3568_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(1), 765*33a014bdSDavid Wu 766*33a014bdSDavid Wu RK3568_TXCLK_DLY_ENA_GMAC_MASK = BIT(0), 767*33a014bdSDavid Wu RK3568_TXCLK_DLY_ENA_GMAC_DISABLE = 0, 768*33a014bdSDavid Wu RK3568_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(0), 769*33a014bdSDavid Wu }; 770*33a014bdSDavid Wu 771*33a014bdSDavid Wu enum { 772*33a014bdSDavid Wu RK3568_CLK_RX_DL_CFG_GMAC_SHIFT = 0x8, 773*33a014bdSDavid Wu RK3568_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(15, 8), 774*33a014bdSDavid Wu 775*33a014bdSDavid Wu RK3568_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0, 776*33a014bdSDavid Wu RK3568_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(7, 0), 777*33a014bdSDavid Wu }; 778*33a014bdSDavid Wu 779*33a014bdSDavid Wu grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 780*33a014bdSDavid Wu 781*33a014bdSDavid Wu if (pdata->bus_id == 1) { 782*33a014bdSDavid Wu con0 = &grf->mac1_con0; 783*33a014bdSDavid Wu con1 = &grf->mac1_con1; 784*33a014bdSDavid Wu } else { 785*33a014bdSDavid Wu con0 = &grf->mac0_con0; 786*33a014bdSDavid Wu con1 = &grf->mac0_con1; 787*33a014bdSDavid Wu } 788*33a014bdSDavid Wu 789*33a014bdSDavid Wu rk_clrsetreg(con0, 790*33a014bdSDavid Wu RK3568_CLK_RX_DL_CFG_GMAC_MASK | 791*33a014bdSDavid Wu RK3568_CLK_TX_DL_CFG_GMAC_MASK, 792*33a014bdSDavid Wu pdata->rx_delay << RK3568_CLK_RX_DL_CFG_GMAC_SHIFT | 793*33a014bdSDavid Wu pdata->tx_delay << RK3568_CLK_TX_DL_CFG_GMAC_SHIFT); 794*33a014bdSDavid Wu 795*33a014bdSDavid Wu rk_clrsetreg(con1, 796*33a014bdSDavid Wu RK3568_TXCLK_DLY_ENA_GMAC_MASK | 797*33a014bdSDavid Wu RK3568_RXCLK_DLY_ENA_GMAC_MASK | 798*33a014bdSDavid Wu RK3568_GMAC_PHY_INTF_SEL_MASK, 799*33a014bdSDavid Wu RK3568_TXCLK_DLY_ENA_GMAC_ENABLE | 800*33a014bdSDavid Wu RK3568_RXCLK_DLY_ENA_GMAC_ENABLE | 801*33a014bdSDavid Wu RK3568_GMAC_PHY_INTF_SEL_RGMII); 802*33a014bdSDavid Wu } 803*33a014bdSDavid Wu 804e4e3f431SDavid Wu static void rv1126_set_to_rmii(struct gmac_rockchip_platdata *pdata) 805e4e3f431SDavid Wu { 806e4e3f431SDavid Wu struct rv1126_grf *grf; 807e4e3f431SDavid Wu 808e4e3f431SDavid Wu enum { 809e4e3f431SDavid Wu RV1126_GMAC_PHY_INTF_SEL_SHIFT = 4, 810e4e3f431SDavid Wu RV1126_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4), 811e4e3f431SDavid Wu RV1126_GMAC_PHY_INTF_SEL_RMII = BIT(6), 812e4e3f431SDavid Wu }; 813e4e3f431SDavid Wu 814e4e3f431SDavid Wu grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 815e4e3f431SDavid Wu 816e4e3f431SDavid Wu rk_clrsetreg(&grf->mac_con0, 817e4e3f431SDavid Wu RV1126_GMAC_PHY_INTF_SEL_MASK, 818e4e3f431SDavid Wu RV1126_GMAC_PHY_INTF_SEL_RMII); 819e4e3f431SDavid Wu } 820e4e3f431SDavid Wu 821dcfb333aSDavid Wu static void rv1126_set_to_rgmii(struct gmac_rockchip_platdata *pdata) 822dcfb333aSDavid Wu { 823dcfb333aSDavid Wu struct rv1126_grf *grf; 824dcfb333aSDavid Wu 825dcfb333aSDavid Wu enum { 826dcfb333aSDavid Wu RV1126_GMAC_PHY_INTF_SEL_SHIFT = 4, 827dcfb333aSDavid Wu RV1126_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4), 828dcfb333aSDavid Wu RV1126_GMAC_PHY_INTF_SEL_RGMII = BIT(4), 829dcfb333aSDavid Wu 830dcfb333aSDavid Wu RV1126_RXCLK_M1_DLY_ENA_GMAC_MASK = BIT(3), 831dcfb333aSDavid Wu RV1126_RXCLK_M1_DLY_ENA_GMAC_DISABLE = 0, 832dcfb333aSDavid Wu RV1126_RXCLK_M1_DLY_ENA_GMAC_ENABLE = BIT(3), 833dcfb333aSDavid Wu 834dcfb333aSDavid Wu RV1126_TXCLK_M1_DLY_ENA_GMAC_MASK = BIT(2), 835dcfb333aSDavid Wu RV1126_TXCLK_M1_DLY_ENA_GMAC_DISABLE = 0, 836dcfb333aSDavid Wu RV1126_TXCLK_M1_DLY_ENA_GMAC_ENABLE = BIT(2), 837dcfb333aSDavid Wu 838dcfb333aSDavid Wu RV1126_RXCLK_M0_DLY_ENA_GMAC_MASK = BIT(1), 839dcfb333aSDavid Wu RV1126_RXCLK_M0_DLY_ENA_GMAC_DISABLE = 0, 840dcfb333aSDavid Wu RV1126_RXCLK_M0_DLY_ENA_GMAC_ENABLE = BIT(1), 841dcfb333aSDavid Wu 842dcfb333aSDavid Wu RV1126_TXCLK_M0_DLY_ENA_GMAC_MASK = BIT(0), 843dcfb333aSDavid Wu RV1126_TXCLK_M0_DLY_ENA_GMAC_DISABLE = 0, 844dcfb333aSDavid Wu RV1126_TXCLK_M0_DLY_ENA_GMAC_ENABLE = BIT(0), 845dcfb333aSDavid Wu }; 846dcfb333aSDavid Wu enum { 847dcfb333aSDavid Wu RV1126_M0_CLK_RX_DL_CFG_GMAC_SHIFT = 0x8, 848dcfb333aSDavid Wu RV1126_M0_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(14, 8), 849dcfb333aSDavid Wu 850dcfb333aSDavid Wu RV1126_M0_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0, 851dcfb333aSDavid Wu RV1126_M0_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0), 852dcfb333aSDavid Wu }; 853dcfb333aSDavid Wu enum { 854dcfb333aSDavid Wu RV1126_M1_CLK_RX_DL_CFG_GMAC_SHIFT = 0x8, 855dcfb333aSDavid Wu RV1126_M1_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(14, 8), 856dcfb333aSDavid Wu 857dcfb333aSDavid Wu RV1126_M1_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0, 858dcfb333aSDavid Wu RV1126_M1_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0), 859dcfb333aSDavid Wu }; 860dcfb333aSDavid Wu 861dcfb333aSDavid Wu grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 862dcfb333aSDavid Wu 863dcfb333aSDavid Wu rk_clrsetreg(&grf->mac_con0, 864dcfb333aSDavid Wu RV1126_TXCLK_M0_DLY_ENA_GMAC_MASK | 865dcfb333aSDavid Wu RV1126_RXCLK_M0_DLY_ENA_GMAC_MASK | 866dcfb333aSDavid Wu RV1126_TXCLK_M1_DLY_ENA_GMAC_MASK | 867dcfb333aSDavid Wu RV1126_RXCLK_M1_DLY_ENA_GMAC_MASK | 868dcfb333aSDavid Wu RV1126_GMAC_PHY_INTF_SEL_MASK, 869dcfb333aSDavid Wu RV1126_TXCLK_M0_DLY_ENA_GMAC_ENABLE | 870dcfb333aSDavid Wu RV1126_RXCLK_M0_DLY_ENA_GMAC_ENABLE | 871dcfb333aSDavid Wu RV1126_TXCLK_M1_DLY_ENA_GMAC_ENABLE | 872dcfb333aSDavid Wu RV1126_RXCLK_M1_DLY_ENA_GMAC_ENABLE | 873dcfb333aSDavid Wu RV1126_GMAC_PHY_INTF_SEL_RGMII); 874dcfb333aSDavid Wu 875dcfb333aSDavid Wu rk_clrsetreg(&grf->mac_con1, 876dcfb333aSDavid Wu RV1126_M0_CLK_RX_DL_CFG_GMAC_MASK | 877dcfb333aSDavid Wu RV1126_M0_CLK_TX_DL_CFG_GMAC_MASK, 878dcfb333aSDavid Wu pdata->rx_delay << RV1126_M0_CLK_RX_DL_CFG_GMAC_SHIFT | 879dcfb333aSDavid Wu pdata->tx_delay << RV1126_M0_CLK_TX_DL_CFG_GMAC_SHIFT); 880dcfb333aSDavid Wu 881dcfb333aSDavid Wu rk_clrsetreg(&grf->mac_con2, 882dcfb333aSDavid Wu RV1126_M1_CLK_RX_DL_CFG_GMAC_MASK | 883dcfb333aSDavid Wu RV1126_M1_CLK_TX_DL_CFG_GMAC_MASK, 884dcfb333aSDavid Wu pdata->rx_delay << RV1126_M1_CLK_RX_DL_CFG_GMAC_SHIFT | 885dcfb333aSDavid Wu pdata->tx_delay << RV1126_M1_CLK_TX_DL_CFG_GMAC_SHIFT); 886dcfb333aSDavid Wu } 8876f0a52e9SDavid Wu #endif 8880a33ce65SDavid Wu 8890125bcf0SSjoerd Simons static int gmac_rockchip_probe(struct udevice *dev) 8900125bcf0SSjoerd Simons { 8910125bcf0SSjoerd Simons struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); 8921f08aa1cSPhilipp Tomsich struct rk_gmac_ops *ops = 8931f08aa1cSPhilipp Tomsich (struct rk_gmac_ops *)dev_get_driver_data(dev); 8946f0a52e9SDavid Wu #ifdef CONFIG_DWC_ETH_QOS 8956f0a52e9SDavid Wu struct eqos_config *config; 8966f0a52e9SDavid Wu #else 8976f0a52e9SDavid Wu struct dw_eth_pdata *dw_pdata; 8986f0a52e9SDavid Wu #endif 8996f0a52e9SDavid Wu struct eth_pdata *eth_pdata; 9000125bcf0SSjoerd Simons struct clk clk; 9010a33ce65SDavid Wu ulong rate; 9020125bcf0SSjoerd Simons int ret; 9030125bcf0SSjoerd Simons 9046f0a52e9SDavid Wu #ifdef CONFIG_DWC_ETH_QOS 9056f0a52e9SDavid Wu eth_pdata = &pdata->eth_pdata; 9066f0a52e9SDavid Wu config = (struct eqos_config *)&ops->config; 907befcb627SDavid Wu memcpy(config, &eqos_rockchip_config, sizeof(struct eqos_config)); 9086f0a52e9SDavid Wu eth_pdata->phy_interface = config->ops->eqos_get_interface(dev); 9096f0a52e9SDavid Wu #else 9106f0a52e9SDavid Wu dw_pdata = &pdata->dw_eth_pdata; 9116f0a52e9SDavid Wu eth_pdata = &dw_pdata->eth_pdata; 9126f0a52e9SDavid Wu #endif 913*33a014bdSDavid Wu pdata->bus_id = dev->seq; 914cadc8d74SKever Yang /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ 915cadc8d74SKever Yang ret = clk_set_defaults(dev); 916cadc8d74SKever Yang if (ret) 917cadc8d74SKever Yang debug("%s clk_set_defaults failed %d\n", __func__, ret); 918cadc8d74SKever Yang 9190125bcf0SSjoerd Simons ret = clk_get_by_index(dev, 0, &clk); 9200125bcf0SSjoerd Simons if (ret) 9210125bcf0SSjoerd Simons return ret; 9220125bcf0SSjoerd Simons 9230a33ce65SDavid Wu switch (eth_pdata->phy_interface) { 9240a33ce65SDavid Wu case PHY_INTERFACE_MODE_RGMII: 9250a33ce65SDavid Wu /* 9260a33ce65SDavid Wu * If the gmac clock is from internal pll, need to set and 9270a33ce65SDavid Wu * check the return value for gmac clock at RGMII mode. If 9280a33ce65SDavid Wu * the gmac clock is from external source, the clock rate 9290a33ce65SDavid Wu * is not set, because of it is bypassed. 9300a33ce65SDavid Wu */ 9310a33ce65SDavid Wu if (!pdata->clock_input) { 9320a33ce65SDavid Wu rate = clk_set_rate(&clk, 125000000); 9330a33ce65SDavid Wu if (rate != 125000000) 9340a33ce65SDavid Wu return -EINVAL; 9350a33ce65SDavid Wu } 9360125bcf0SSjoerd Simons 9370125bcf0SSjoerd Simons /* Set to RGMII mode */ 9380a33ce65SDavid Wu if (ops->set_to_rgmii) 9391f08aa1cSPhilipp Tomsich ops->set_to_rgmii(pdata); 9400a33ce65SDavid Wu else 9410a33ce65SDavid Wu return -EPERM; 9420a33ce65SDavid Wu 9430a33ce65SDavid Wu break; 9440a33ce65SDavid Wu case PHY_INTERFACE_MODE_RMII: 9450a33ce65SDavid Wu /* The commet is the same as RGMII mode */ 9460a33ce65SDavid Wu if (!pdata->clock_input) { 9470a33ce65SDavid Wu rate = clk_set_rate(&clk, 50000000); 9480a33ce65SDavid Wu if (rate != 50000000) 9490a33ce65SDavid Wu return -EINVAL; 9500a33ce65SDavid Wu } 9510a33ce65SDavid Wu 9520a33ce65SDavid Wu /* Set to RMII mode */ 9530a33ce65SDavid Wu if (ops->set_to_rmii) 9540a33ce65SDavid Wu ops->set_to_rmii(pdata); 9550a33ce65SDavid Wu else 9560a33ce65SDavid Wu return -EPERM; 9570a33ce65SDavid Wu 9580a33ce65SDavid Wu break; 9590a33ce65SDavid Wu default: 9600a33ce65SDavid Wu debug("NO interface defined!\n"); 9610a33ce65SDavid Wu return -ENXIO; 9620a33ce65SDavid Wu } 9630125bcf0SSjoerd Simons 9646f0a52e9SDavid Wu #ifdef CONFIG_DWC_ETH_QOS 9656f0a52e9SDavid Wu return eqos_probe(dev); 9666f0a52e9SDavid Wu #else 9670125bcf0SSjoerd Simons return designware_eth_probe(dev); 9686f0a52e9SDavid Wu #endif 9696f0a52e9SDavid Wu } 9706f0a52e9SDavid Wu 9716f0a52e9SDavid Wu static int gmac_rockchip_eth_write_hwaddr(struct udevice *dev) 9726f0a52e9SDavid Wu { 9736f0a52e9SDavid Wu #if defined(CONFIG_DWC_ETH_QOS) 9746f0a52e9SDavid Wu return eqos_write_hwaddr(dev); 9756f0a52e9SDavid Wu #else 9766f0a52e9SDavid Wu return designware_eth_write_hwaddr(dev); 9776f0a52e9SDavid Wu #endif 9786f0a52e9SDavid Wu } 9796f0a52e9SDavid Wu 9806f0a52e9SDavid Wu static int gmac_rockchip_eth_free_pkt(struct udevice *dev, uchar *packet, 9816f0a52e9SDavid Wu int length) 9826f0a52e9SDavid Wu { 9836f0a52e9SDavid Wu #ifdef CONFIG_DWC_ETH_QOS 9846f0a52e9SDavid Wu return eqos_free_pkt(dev, packet, length); 9856f0a52e9SDavid Wu #else 9866f0a52e9SDavid Wu return designware_eth_free_pkt(dev, packet, length); 9876f0a52e9SDavid Wu #endif 9886f0a52e9SDavid Wu } 9896f0a52e9SDavid Wu 9906f0a52e9SDavid Wu static int gmac_rockchip_eth_send(struct udevice *dev, void *packet, 9916f0a52e9SDavid Wu int length) 9926f0a52e9SDavid Wu { 9936f0a52e9SDavid Wu #ifdef CONFIG_DWC_ETH_QOS 9946f0a52e9SDavid Wu return eqos_send(dev, packet, length); 9956f0a52e9SDavid Wu #else 9966f0a52e9SDavid Wu return designware_eth_send(dev, packet, length); 9976f0a52e9SDavid Wu #endif 9986f0a52e9SDavid Wu } 9996f0a52e9SDavid Wu 10006f0a52e9SDavid Wu static int gmac_rockchip_eth_recv(struct udevice *dev, int flags, 10016f0a52e9SDavid Wu uchar **packetp) 10026f0a52e9SDavid Wu { 10036f0a52e9SDavid Wu #ifdef CONFIG_DWC_ETH_QOS 10046f0a52e9SDavid Wu return eqos_recv(dev, flags, packetp); 10056f0a52e9SDavid Wu #else 10066f0a52e9SDavid Wu return designware_eth_recv(dev, flags, packetp); 10076f0a52e9SDavid Wu #endif 10080125bcf0SSjoerd Simons } 10090125bcf0SSjoerd Simons 10100125bcf0SSjoerd Simons static int gmac_rockchip_eth_start(struct udevice *dev) 10110125bcf0SSjoerd Simons { 10126f0a52e9SDavid Wu struct rockchip_eth_dev *priv = dev_get_priv(dev); 10131f08aa1cSPhilipp Tomsich struct rk_gmac_ops *ops = 10141f08aa1cSPhilipp Tomsich (struct rk_gmac_ops *)dev_get_driver_data(dev); 10156f0a52e9SDavid Wu #ifndef CONFIG_DWC_ETH_QOS 10166f0a52e9SDavid Wu struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); 10176f0a52e9SDavid Wu struct dw_eth_pdata *dw_pdata; 10186f0a52e9SDavid Wu struct eth_pdata *eth_pdata; 10196f0a52e9SDavid Wu #endif 10200125bcf0SSjoerd Simons int ret; 10210125bcf0SSjoerd Simons 10226f0a52e9SDavid Wu #ifdef CONFIG_DWC_ETH_QOS 10236f0a52e9SDavid Wu ret = eqos_init(dev); 10246f0a52e9SDavid Wu #else 10256f0a52e9SDavid Wu dw_pdata = &pdata->dw_eth_pdata; 10266f0a52e9SDavid Wu eth_pdata = &dw_pdata->eth_pdata; 10276f0a52e9SDavid Wu ret = designware_eth_init((struct dw_eth_dev *)priv, 10286f0a52e9SDavid Wu eth_pdata->enetaddr); 10296f0a52e9SDavid Wu #endif 10300125bcf0SSjoerd Simons if (ret) 10310125bcf0SSjoerd Simons return ret; 10321f08aa1cSPhilipp Tomsich ret = ops->fix_mac_speed(priv); 10330125bcf0SSjoerd Simons if (ret) 10340125bcf0SSjoerd Simons return ret; 10356f0a52e9SDavid Wu 10366f0a52e9SDavid Wu #ifdef CONFIG_DWC_ETH_QOS 10376f0a52e9SDavid Wu eqos_enable(dev); 10386f0a52e9SDavid Wu #else 10396f0a52e9SDavid Wu ret = designware_eth_enable((struct dw_eth_dev *)priv); 10400125bcf0SSjoerd Simons if (ret) 10410125bcf0SSjoerd Simons return ret; 10426f0a52e9SDavid Wu #endif 10430125bcf0SSjoerd Simons 10440125bcf0SSjoerd Simons return 0; 10450125bcf0SSjoerd Simons } 10460125bcf0SSjoerd Simons 10476f0a52e9SDavid Wu static void gmac_rockchip_eth_stop(struct udevice *dev) 10486f0a52e9SDavid Wu { 10496f0a52e9SDavid Wu #ifdef CONFIG_DWC_ETH_QOS 10506f0a52e9SDavid Wu eqos_stop(dev); 10516f0a52e9SDavid Wu #else 10526f0a52e9SDavid Wu designware_eth_stop(dev); 10536f0a52e9SDavid Wu #endif 10546f0a52e9SDavid Wu } 10556f0a52e9SDavid Wu 10560125bcf0SSjoerd Simons const struct eth_ops gmac_rockchip_eth_ops = { 10570125bcf0SSjoerd Simons .start = gmac_rockchip_eth_start, 10586f0a52e9SDavid Wu .send = gmac_rockchip_eth_send, 10596f0a52e9SDavid Wu .recv = gmac_rockchip_eth_recv, 10606f0a52e9SDavid Wu .free_pkt = gmac_rockchip_eth_free_pkt, 10616f0a52e9SDavid Wu .stop = gmac_rockchip_eth_stop, 10626f0a52e9SDavid Wu .write_hwaddr = gmac_rockchip_eth_write_hwaddr, 10630125bcf0SSjoerd Simons }; 10640125bcf0SSjoerd Simons 10656f0a52e9SDavid Wu #ifndef CONFIG_DWC_ETH_QOS 106618ae91c8SDavid Wu const struct rk_gmac_ops px30_gmac_ops = { 106718ae91c8SDavid Wu .fix_mac_speed = px30_gmac_fix_mac_speed, 106818ae91c8SDavid Wu .set_to_rmii = px30_gmac_set_to_rmii, 106918ae91c8SDavid Wu }; 107018ae91c8SDavid Wu 1071ff86648dSDavid Wu const struct rk_gmac_ops rk1808_gmac_ops = { 1072ff86648dSDavid Wu .fix_mac_speed = rk1808_gmac_fix_mac_speed, 1073ff86648dSDavid Wu .set_to_rgmii = rk1808_gmac_set_to_rgmii, 1074ff86648dSDavid Wu }; 1075ff86648dSDavid Wu 1076af166ffaSDavid Wu const struct rk_gmac_ops rk3228_gmac_ops = { 1077af166ffaSDavid Wu .fix_mac_speed = rk3228_gmac_fix_mac_speed, 1078af166ffaSDavid Wu .set_to_rgmii = rk3228_gmac_set_to_rgmii, 1079af166ffaSDavid Wu }; 1080af166ffaSDavid Wu 10811f08aa1cSPhilipp Tomsich const struct rk_gmac_ops rk3288_gmac_ops = { 10821f08aa1cSPhilipp Tomsich .fix_mac_speed = rk3288_gmac_fix_mac_speed, 10831f08aa1cSPhilipp Tomsich .set_to_rgmii = rk3288_gmac_set_to_rgmii, 10841f08aa1cSPhilipp Tomsich }; 10851f08aa1cSPhilipp Tomsich 108623adb58fSDavid Wu const struct rk_gmac_ops rk3308_gmac_ops = { 108723adb58fSDavid Wu .fix_mac_speed = rk3308_gmac_fix_mac_speed, 108823adb58fSDavid Wu .set_to_rmii = rk3308_gmac_set_to_rmii, 108923adb58fSDavid Wu }; 109023adb58fSDavid Wu 1091c36b26c0SDavid Wu const struct rk_gmac_ops rk3328_gmac_ops = { 1092c36b26c0SDavid Wu .fix_mac_speed = rk3328_gmac_fix_mac_speed, 1093c36b26c0SDavid Wu .set_to_rgmii = rk3328_gmac_set_to_rgmii, 1094c36b26c0SDavid Wu }; 1095c36b26c0SDavid Wu 1096793f2fd2SPhilipp Tomsich const struct rk_gmac_ops rk3368_gmac_ops = { 1097793f2fd2SPhilipp Tomsich .fix_mac_speed = rk3368_gmac_fix_mac_speed, 1098793f2fd2SPhilipp Tomsich .set_to_rgmii = rk3368_gmac_set_to_rgmii, 1099793f2fd2SPhilipp Tomsich }; 1100793f2fd2SPhilipp Tomsich 11011f08aa1cSPhilipp Tomsich const struct rk_gmac_ops rk3399_gmac_ops = { 11021f08aa1cSPhilipp Tomsich .fix_mac_speed = rk3399_gmac_fix_mac_speed, 11031f08aa1cSPhilipp Tomsich .set_to_rgmii = rk3399_gmac_set_to_rgmii, 11041f08aa1cSPhilipp Tomsich }; 11051f08aa1cSPhilipp Tomsich 11060a33ce65SDavid Wu const struct rk_gmac_ops rv1108_gmac_ops = { 11070a33ce65SDavid Wu .fix_mac_speed = rv1108_set_rmii_speed, 11080a33ce65SDavid Wu .set_to_rmii = rv1108_gmac_set_to_rmii, 11090a33ce65SDavid Wu }; 1110dcfb333aSDavid Wu #else 1111*33a014bdSDavid Wu const struct rk_gmac_ops rk3568_gmac_ops = { 1112*33a014bdSDavid Wu .fix_mac_speed = rv1126_set_rgmii_speed, 1113*33a014bdSDavid Wu .set_to_rgmii = rk3568_set_to_rgmii, 1114*33a014bdSDavid Wu .set_to_rmii = rk3568_set_to_rmii, 1115*33a014bdSDavid Wu }; 1116*33a014bdSDavid Wu 1117dcfb333aSDavid Wu const struct rk_gmac_ops rv1126_gmac_ops = { 1118dcfb333aSDavid Wu .fix_mac_speed = rv1126_set_rgmii_speed, 1119dcfb333aSDavid Wu .set_to_rgmii = rv1126_set_to_rgmii, 1120e4e3f431SDavid Wu .set_to_rmii = rv1126_set_to_rmii, 1121dcfb333aSDavid Wu }; 11226f0a52e9SDavid Wu #endif 11230a33ce65SDavid Wu 11240125bcf0SSjoerd Simons static const struct udevice_id rockchip_gmac_ids[] = { 11256f0a52e9SDavid Wu #ifndef CONFIG_DWC_ETH_QOS 112618ae91c8SDavid Wu { .compatible = "rockchip,px30-gmac", 112718ae91c8SDavid Wu .data = (ulong)&px30_gmac_ops }, 1128ff86648dSDavid Wu { .compatible = "rockchip,rk1808-gmac", 1129ff86648dSDavid Wu .data = (ulong)&rk1808_gmac_ops }, 1130af166ffaSDavid Wu { .compatible = "rockchip,rk3228-gmac", 1131af166ffaSDavid Wu .data = (ulong)&rk3228_gmac_ops }, 11321f08aa1cSPhilipp Tomsich { .compatible = "rockchip,rk3288-gmac", 11331f08aa1cSPhilipp Tomsich .data = (ulong)&rk3288_gmac_ops }, 113423adb58fSDavid Wu { .compatible = "rockchip,rk3308-mac", 113523adb58fSDavid Wu .data = (ulong)&rk3308_gmac_ops }, 1136c36b26c0SDavid Wu { .compatible = "rockchip,rk3328-gmac", 1137c36b26c0SDavid Wu .data = (ulong)&rk3328_gmac_ops }, 1138793f2fd2SPhilipp Tomsich { .compatible = "rockchip,rk3368-gmac", 1139793f2fd2SPhilipp Tomsich .data = (ulong)&rk3368_gmac_ops }, 11401f08aa1cSPhilipp Tomsich { .compatible = "rockchip,rk3399-gmac", 11411f08aa1cSPhilipp Tomsich .data = (ulong)&rk3399_gmac_ops }, 11420a33ce65SDavid Wu { .compatible = "rockchip,rv1108-gmac", 11430a33ce65SDavid Wu .data = (ulong)&rv1108_gmac_ops }, 1144dcfb333aSDavid Wu #else 1145*33a014bdSDavid Wu { .compatible = "rockchip,rk3568-gmac", 1146*33a014bdSDavid Wu .data = (ulong)&rk3568_gmac_ops }, 1147dcfb333aSDavid Wu { .compatible = "rockchip,rv1126-gmac", 1148dcfb333aSDavid Wu .data = (ulong)&rv1126_gmac_ops }, 11496f0a52e9SDavid Wu #endif 11500125bcf0SSjoerd Simons { } 11510125bcf0SSjoerd Simons }; 11520125bcf0SSjoerd Simons 11530125bcf0SSjoerd Simons U_BOOT_DRIVER(eth_gmac_rockchip) = { 11540125bcf0SSjoerd Simons .name = "gmac_rockchip", 11550125bcf0SSjoerd Simons .id = UCLASS_ETH, 11560125bcf0SSjoerd Simons .of_match = rockchip_gmac_ids, 11570125bcf0SSjoerd Simons .ofdata_to_platdata = gmac_rockchip_ofdata_to_platdata, 11580125bcf0SSjoerd Simons .probe = gmac_rockchip_probe, 11590125bcf0SSjoerd Simons .ops = &gmac_rockchip_eth_ops, 11606f0a52e9SDavid Wu .priv_auto_alloc_size = sizeof(struct rockchip_eth_dev), 11610125bcf0SSjoerd Simons .platdata_auto_alloc_size = sizeof(struct gmac_rockchip_platdata), 11620125bcf0SSjoerd Simons .flags = DM_FLAG_ALLOC_PRIV_DMA, 11630125bcf0SSjoerd Simons }; 1164