diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3288.h b/arch/arm/include/asm/arch-rockchip/grf_rk3288.h
index aaffd19dea7071edf8d1026e2ece42069e3a3c6e..1a7c8199c3810ee9a8b5d86b689303afdbd36664 100644
--- a/arch/arm/include/asm/arch-rockchip/grf_rk3288.h
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk3288.h
@@ -720,20 +720,20 @@ enum {
 
 /* GRF_SOC_CON1 */
 enum {
-	RMII_MODE_SHIFT = 0xe,
-	RMII_MODE_MASK = 1,
-	RMII_MODE = 1,
+	RK3288_RMII_MODE_SHIFT = 14,
+	RK3288_RMII_MODE_MASK  = (1 << RK3288_RMII_MODE_SHIFT),
+	RK3288_RMII_MODE       = (1 << RK3288_RMII_MODE_SHIFT),
 
-	GMAC_CLK_SEL_SHIFT	= 0xc,
-	GMAC_CLK_SEL_MASK	= 3,
-	GMAC_CLK_SEL_125M	= 0,
-	GMAC_CLK_SEL_25M	= 0x3,
-	GMAC_CLK_SEL_2_5M	= 0x2,
+	RK3288_GMAC_CLK_SEL_SHIFT = 12,
+	RK3288_GMAC_CLK_SEL_MASK  = (3 << RK3288_GMAC_CLK_SEL_SHIFT),
+	RK3288_GMAC_CLK_SEL_125M  = (0 << RK3288_GMAC_CLK_SEL_SHIFT),
+	RK3288_GMAC_CLK_SEL_25M   = (3 << RK3288_GMAC_CLK_SEL_SHIFT),
+	RK3288_GMAC_CLK_SEL_2_5M  = (2 << RK3288_GMAC_CLK_SEL_SHIFT),
 
-	RMII_CLK_SEL_SHIFT	= 0xb,
-	RMII_CLK_SEL_MASK	= 1,
-	RMII_CLK_SEL_2_5M	= 0,
-	RMII_CLK_SEL_25M,
+	RK3288_RMII_CLK_SEL_SHIFT = 11,
+	RK3288_RMII_CLK_SEL_MASK  = (1 << RK3288_RMII_CLK_SEL_SHIFT),
+	RK3288_RMII_CLK_SEL_2_5M  = (0 << RK3288_RMII_CLK_SEL_SHIFT),
+	RK3288_RMII_CLK_SEL_25M   = (1 << RK3288_RMII_CLK_SEL_SHIFT),
 
 	GMAC_SPEED_SHIFT	= 0xa,
 	GMAC_SPEED_MASK		= 1,
@@ -743,10 +743,10 @@ enum {
 	GMAC_FLOWCTRL_SHIFT	= 0x9,
 	GMAC_FLOWCTRL_MASK	= 1,
 
-	GMAC_PHY_INTF_SEL_SHIFT	= 0x6,
-	GMAC_PHY_INTF_SEL_MASK	= 0x7,
-	GMAC_PHY_INTF_SEL_RGMII	= 0x1,
-	GMAC_PHY_INTF_SEL_RMII	= 0x4,
+	RK3288_GMAC_PHY_INTF_SEL_SHIFT = 6,
+	RK3288_GMAC_PHY_INTF_SEL_MASK  = (7 << RK3288_GMAC_PHY_INTF_SEL_SHIFT),
+	RK3288_GMAC_PHY_INTF_SEL_RGMII = (1 << RK3288_GMAC_PHY_INTF_SEL_SHIFT),
+	RK3288_GMAC_PHY_INTF_SEL_RMII  = (4 << RK3288_GMAC_PHY_INTF_SEL_SHIFT),
 
 	HOST_REMAP_SHIFT	= 0x5,
 	HOST_REMAP_MASK		= 1
@@ -801,21 +801,27 @@ enum {
 
 /* GRF_SOC_CON3 */
 enum {
-	RXCLK_DLY_ENA_GMAC_SHIFT	= 0xf,
-	RXCLK_DLY_ENA_GMAC_MASK		= 1,
-	RXCLK_DLY_ENA_GMAC_DISABLE	= 0,
-	RXCLK_DLY_ENA_GMAC_ENABLE,
-
-	TXCLK_DLY_ENA_GMAC_SHIFT	= 0xe,
-	TXCLK_DLY_ENA_GMAC_MASK		= 1,
-	TXCLK_DLY_ENA_GMAC_DISABLE	= 0,
-	TXCLK_DLY_ENA_GMAC_ENABLE,
-
-	CLK_RX_DL_CFG_GMAC_SHIFT	= 0x7,
-	CLK_RX_DL_CFG_GMAC_MASK		= 0x7f,
-
-	CLK_TX_DL_CFG_GMAC_SHIFT	= 0x0,
-	CLK_TX_DL_CFG_GMAC_MASK		= 0x7f,
+	RK3288_RXCLK_DLY_ENA_GMAC_SHIFT = 0xf,
+	RK3288_RXCLK_DLY_ENA_GMAC_MASK =
+		(1 << RK3288_RXCLK_DLY_ENA_GMAC_SHIFT),
+	RK3288_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
+	RK3288_RXCLK_DLY_ENA_GMAC_ENABLE =
+		(1 << RK3288_RXCLK_DLY_ENA_GMAC_SHIFT),
+
+	RK3288_TXCLK_DLY_ENA_GMAC_SHIFT = 0xe,
+	RK3288_TXCLK_DLY_ENA_GMAC_MASK =
+		(1 << RK3288_TXCLK_DLY_ENA_GMAC_SHIFT),
+	RK3288_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
+	RK3288_TXCLK_DLY_ENA_GMAC_ENABLE =
+		(1 << RK3288_RXCLK_DLY_ENA_GMAC_SHIFT),
+
+	RK3288_CLK_RX_DL_CFG_GMAC_SHIFT = 0x7,
+	RK3288_CLK_RX_DL_CFG_GMAC_MASK =
+		(0x7f << RK3288_CLK_RX_DL_CFG_GMAC_SHIFT),
+
+	RK3288_CLK_TX_DL_CFG_GMAC_SHIFT = 0x0,
+	RK3288_CLK_TX_DL_CFG_GMAC_MASK =
+		(0x7f << RK3288_CLK_TX_DL_CFG_GMAC_SHIFT),
 };
 
 #endif
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3399.h b/arch/arm/include/asm/arch-rockchip/grf_rk3399.h
index e709fdaad20a2a74acc55d4a3408b5b3b2e2a4b4..b340b05e36e995871d164f8ce1c50bf4895d34fe 100644
--- a/arch/arm/include/asm/arch-rockchip/grf_rk3399.h
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk3399.h
@@ -144,7 +144,9 @@ struct rk3399_grf_regs {
 	};
 	u32 gpio4d_iomux;
 	u32 reserved21[4];
-	u32 gpio2_p[3][4];
+	u32 gpio2_p[4];
+	u32 gpio3_p[4];
+	u32 gpio4_p[4];
 	u32 reserved22[4];
 	u32 gpio2_sr[3][4];
 	u32 reserved23[4];
@@ -215,7 +217,9 @@ struct rk3399_pmugrf_regs {
 	};
 	u32 gpio1d_iomux;
 	u32 reserved1[8];
-	u32 gpio0_p[2][4];
+	u32 gpio0_p[2];
+	u32 reserved2[2];
+	u32 gpio1_p[4];
 	u32 reserved3[8];
 	u32 gpio0a_e;
 	u32 reserved4;
@@ -473,4 +477,43 @@ enum {
 
 };
 
+/* GRF_SOC_CON5 */
+enum {
+	RK3399_GMAC_PHY_INTF_SEL_SHIFT = 9,
+	RK3399_GMAC_PHY_INTF_SEL_MASK  = (7 << RK3399_GMAC_PHY_INTF_SEL_SHIFT),
+	RK3399_GMAC_PHY_INTF_SEL_RGMII = (1 << RK3399_GMAC_PHY_INTF_SEL_SHIFT),
+	RK3399_GMAC_PHY_INTF_SEL_RMII  = (4 << RK3399_GMAC_PHY_INTF_SEL_SHIFT),
+
+	RK3399_GMAC_CLK_SEL_SHIFT = 4,
+	RK3399_GMAC_CLK_SEL_MASK  = (3 << RK3399_GMAC_CLK_SEL_SHIFT),
+	RK3399_GMAC_CLK_SEL_125M  = (0 << RK3399_GMAC_CLK_SEL_SHIFT),
+	RK3399_GMAC_CLK_SEL_25M	  = (3 << RK3399_GMAC_CLK_SEL_SHIFT),
+	RK3399_GMAC_CLK_SEL_2_5M  = (2 << RK3399_GMAC_CLK_SEL_SHIFT),
+};
+
+/* GRF_SOC_CON6 */
+enum {
+	RK3399_RXCLK_DLY_ENA_GMAC_SHIFT = 15,
+	RK3399_RXCLK_DLY_ENA_GMAC_MASK =
+		(1 << RK3399_RXCLK_DLY_ENA_GMAC_SHIFT),
+	RK3399_RXCLK_DLY_ENA_GMAC_DISABLE = 0,
+	RK3399_RXCLK_DLY_ENA_GMAC_ENABLE =
+		(1 << RK3399_RXCLK_DLY_ENA_GMAC_SHIFT),
+
+	RK3399_TXCLK_DLY_ENA_GMAC_SHIFT	= 7,
+	RK3399_TXCLK_DLY_ENA_GMAC_MASK =
+		(1 << RK3399_TXCLK_DLY_ENA_GMAC_SHIFT),
+	RK3399_TXCLK_DLY_ENA_GMAC_DISABLE = 0,
+	RK3399_TXCLK_DLY_ENA_GMAC_ENABLE =
+		(1 << RK3399_TXCLK_DLY_ENA_GMAC_SHIFT),
+
+	RK3399_CLK_RX_DL_CFG_GMAC_SHIFT = 8,
+	RK3399_CLK_RX_DL_CFG_GMAC_MASK =
+		(0x7f << RK3399_CLK_RX_DL_CFG_GMAC_SHIFT),
+
+	RK3399_CLK_TX_DL_CFG_GMAC_SHIFT = 0,
+	RK3399_CLK_TX_DL_CFG_GMAC_MASK =
+		(0x7f << RK3399_CLK_TX_DL_CFG_GMAC_SHIFT),
+};
+
 #endif	/* __SOC_ROCKCHIP_RK3399_GRF_H__ */
diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c
index e9b202ab9ae81c26d48f8f943568fc84bf781ab6..5e2ca763027aa5b145265bd1c17c6d7d74873d9a 100644
--- a/drivers/net/gmac_rockchip.c
+++ b/drivers/net/gmac_rockchip.c
@@ -14,7 +14,9 @@
 #include <asm/io.h>
 #include <asm/arch/periph.h>
 #include <asm/arch/clock.h>
+#include <asm/arch/hardware.h>
 #include <asm/arch/grf_rk3288.h>
+#include <asm/arch/grf_rk3399.h>
 #include <dm/pinctrl.h>
 #include <dt-bindings/clock/rk3288-cru.h>
 #include "designware.h"
@@ -32,32 +34,45 @@ struct gmac_rockchip_platdata {
 	int rx_delay;
 };
 
+struct rk_gmac_ops {
+	int (*fix_mac_speed)(struct dw_eth_dev *priv);
+	void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata);
+};
+
+
 static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev)
 {
 	struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
+	const void *blob = gd->fdt_blob;
+	int node = dev_of_offset(dev);
+
+	/* Check the new naming-style first... */
+	pdata->tx_delay = fdtdec_get_int(blob, node, "tx_delay", -ENOENT);
+	pdata->rx_delay = fdtdec_get_int(blob, node, "rx_delay", -ENOENT);
 
-	pdata->tx_delay = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
-					 "tx-delay", 0x30);
-	pdata->rx_delay = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
-					 "rx-delay", 0x10);
+	/* ... and fall back to the old naming style or default, if necessary */
+	if (pdata->tx_delay == -ENOENT)
+		pdata->tx_delay = fdtdec_get_int(blob, node, "tx-delay", 0x30);
+	if (pdata->rx_delay == -ENOENT)
+		pdata->rx_delay = fdtdec_get_int(blob, node, "rx-delay", 0x10);
 
 	return designware_eth_ofdata_to_platdata(dev);
 }
 
-static int gmac_rockchip_fix_mac_speed(struct dw_eth_dev *priv)
+static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv)
 {
 	struct rk3288_grf *grf;
 	int clk;
 
 	switch (priv->phydev->speed) {
 	case 10:
-		clk = GMAC_CLK_SEL_2_5M;
+		clk = RK3288_GMAC_CLK_SEL_2_5M;
 		break;
 	case 100:
-		clk = GMAC_CLK_SEL_25M;
+		clk = RK3288_GMAC_CLK_SEL_25M;
 		break;
 	case 1000:
-		clk = GMAC_CLK_SEL_125M;
+		clk = RK3288_GMAC_CLK_SEL_125M;
 		break;
 	default:
 		debug("Unknown phy speed: %d\n", priv->phydev->speed);
@@ -65,17 +80,83 @@ static int gmac_rockchip_fix_mac_speed(struct dw_eth_dev *priv)
 	}
 
 	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
-	rk_clrsetreg(&grf->soc_con1,
-		     GMAC_CLK_SEL_MASK << GMAC_CLK_SEL_SHIFT,
-		     clk << GMAC_CLK_SEL_SHIFT);
+	rk_clrsetreg(&grf->soc_con1, RK3288_GMAC_CLK_SEL_MASK, clk);
+
+	return 0;
+}
+
+static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv)
+{
+	struct rk3399_grf_regs *grf;
+	int clk;
+
+	switch (priv->phydev->speed) {
+	case 10:
+		clk = RK3399_GMAC_CLK_SEL_2_5M;
+		break;
+	case 100:
+		clk = RK3399_GMAC_CLK_SEL_25M;
+		break;
+	case 1000:
+		clk = RK3399_GMAC_CLK_SEL_125M;
+		break;
+	default:
+		debug("Unknown phy speed: %d\n", priv->phydev->speed);
+		return -EINVAL;
+	}
+
+	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+	rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_CLK_SEL_MASK, clk);
 
 	return 0;
 }
 
+static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
+{
+	struct rk3288_grf *grf;
+
+	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+	rk_clrsetreg(&grf->soc_con1,
+		     RK3288_RMII_MODE_MASK | RK3288_GMAC_PHY_INTF_SEL_MASK,
+		     RK3288_GMAC_PHY_INTF_SEL_RGMII);
+
+	rk_clrsetreg(&grf->soc_con3,
+		     RK3288_RXCLK_DLY_ENA_GMAC_MASK |
+		     RK3288_TXCLK_DLY_ENA_GMAC_MASK |
+		     RK3288_CLK_RX_DL_CFG_GMAC_MASK |
+		     RK3288_CLK_TX_DL_CFG_GMAC_MASK,
+		     RK3288_RXCLK_DLY_ENA_GMAC_ENABLE |
+		     RK3288_TXCLK_DLY_ENA_GMAC_ENABLE |
+		     pdata->rx_delay << RK3288_CLK_RX_DL_CFG_GMAC_SHIFT |
+		     pdata->tx_delay << RK3288_CLK_TX_DL_CFG_GMAC_SHIFT);
+}
+
+static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
+{
+	struct rk3399_grf_regs *grf;
+
+	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+
+	rk_clrsetreg(&grf->soc_con5,
+		     RK3399_GMAC_PHY_INTF_SEL_MASK,
+		     RK3399_GMAC_PHY_INTF_SEL_RGMII);
+
+	rk_clrsetreg(&grf->soc_con6,
+		     RK3399_RXCLK_DLY_ENA_GMAC_MASK |
+		     RK3399_TXCLK_DLY_ENA_GMAC_MASK |
+		     RK3399_CLK_RX_DL_CFG_GMAC_MASK |
+		     RK3399_CLK_TX_DL_CFG_GMAC_MASK,
+		     RK3399_RXCLK_DLY_ENA_GMAC_ENABLE |
+		     RK3399_TXCLK_DLY_ENA_GMAC_ENABLE |
+		     pdata->rx_delay << RK3399_CLK_RX_DL_CFG_GMAC_SHIFT |
+		     pdata->tx_delay << RK3399_CLK_TX_DL_CFG_GMAC_SHIFT);
+}
+
 static int gmac_rockchip_probe(struct udevice *dev)
 {
 	struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev);
-	struct rk3288_grf *grf;
+	struct rk_gmac_ops *ops =
+		(struct rk_gmac_ops *)dev_get_driver_data(dev);
 	struct clk clk;
 	int ret;
 
@@ -89,21 +170,7 @@ static int gmac_rockchip_probe(struct udevice *dev)
 		return ret;
 
 	/* Set to RGMII mode */
-	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
-	rk_clrsetreg(&grf->soc_con1,
-		     RMII_MODE_MASK << RMII_MODE_SHIFT |
-		     GMAC_PHY_INTF_SEL_MASK << GMAC_PHY_INTF_SEL_SHIFT,
-		     GMAC_PHY_INTF_SEL_RGMII << GMAC_PHY_INTF_SEL_SHIFT);
-
-	rk_clrsetreg(&grf->soc_con3,
-		     RXCLK_DLY_ENA_GMAC_MASK <<  RXCLK_DLY_ENA_GMAC_SHIFT |
-		     TXCLK_DLY_ENA_GMAC_MASK <<  TXCLK_DLY_ENA_GMAC_SHIFT |
-		     CLK_RX_DL_CFG_GMAC_MASK <<  CLK_RX_DL_CFG_GMAC_SHIFT |
-		     CLK_TX_DL_CFG_GMAC_MASK <<  CLK_TX_DL_CFG_GMAC_SHIFT,
-		     RXCLK_DLY_ENA_GMAC_ENABLE << RXCLK_DLY_ENA_GMAC_SHIFT |
-		     TXCLK_DLY_ENA_GMAC_ENABLE << TXCLK_DLY_ENA_GMAC_SHIFT |
-		     pdata->rx_delay << CLK_RX_DL_CFG_GMAC_SHIFT |
-		     pdata->tx_delay << CLK_TX_DL_CFG_GMAC_SHIFT);
+	ops->set_to_rgmii(pdata);
 
 	return designware_eth_probe(dev);
 }
@@ -112,12 +179,14 @@ static int gmac_rockchip_eth_start(struct udevice *dev)
 {
 	struct eth_pdata *pdata = dev_get_platdata(dev);
 	struct dw_eth_dev *priv = dev_get_priv(dev);
+	struct rk_gmac_ops *ops =
+		(struct rk_gmac_ops *)dev_get_driver_data(dev);
 	int ret;
 
 	ret = designware_eth_init(priv, pdata->enetaddr);
 	if (ret)
 		return ret;
-	ret = gmac_rockchip_fix_mac_speed(priv);
+	ret = ops->fix_mac_speed(priv);
 	if (ret)
 		return ret;
 	ret = designware_eth_enable(priv);
@@ -136,8 +205,21 @@ const struct eth_ops gmac_rockchip_eth_ops = {
 	.write_hwaddr		= designware_eth_write_hwaddr,
 };
 
+const struct rk_gmac_ops rk3288_gmac_ops = {
+	.fix_mac_speed = rk3288_gmac_fix_mac_speed,
+	.set_to_rgmii = rk3288_gmac_set_to_rgmii,
+};
+
+const struct rk_gmac_ops rk3399_gmac_ops = {
+	.fix_mac_speed = rk3399_gmac_fix_mac_speed,
+	.set_to_rgmii = rk3399_gmac_set_to_rgmii,
+};
+
 static const struct udevice_id rockchip_gmac_ids[] = {
-	{ .compatible = "rockchip,rk3288-gmac" },
+	{ .compatible = "rockchip,rk3288-gmac",
+	  .data = (ulong)&rk3288_gmac_ops },
+	{ .compatible = "rockchip,rk3399-gmac",
+	  .data = (ulong)&rk3399_gmac_ops },
 	{ }
 };