diff --git a/patch/u-boot/v2025.01/board_rk3318-box/general-support-rmii-integrated-phy.patch b/patch/u-boot/v2025.01/board_rk3318-box/general-support-rmii-integrated-phy.patch index 0300299efd..1c64bd7ed8 100644 --- a/patch/u-boot/v2025.01/board_rk3318-box/general-support-rmii-integrated-phy.patch +++ b/patch/u-boot/v2025.01/board_rk3318-box/general-support-rmii-integrated-phy.patch @@ -1,21 +1,84 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From b802c06ab4feb1ad0434ce88c701433063a0fa72 Mon Sep 17 00:00:00 2001 From: Paolo Sabatino -Date: Thu, 25 Apr 2024 21:44:55 +0200 -Subject: support gmac rmii phy for rk322x +Date: Sat, 8 Mar 2025 21:32:37 +0100 +Subject: [PATCH] fix various rockchip gmac drivers --- - arch/arm/dts/rk322x.dtsi | 8 +- - arch/arm/include/asm/arch-rockchip/cru_rk322x.h | 1 + - doc/device-tree-bindings/net/phy.txt | 13 + - drivers/clk/rockchip/clk_rk322x.c | 14 +- - drivers/net/gmac_rockchip.c | 186 +++++++++- - 5 files changed, 205 insertions(+), 17 deletions(-) + arch/arm/dts/rk3229-evb.dts | 32 +- + arch/arm/dts/rk322x.dtsi | 8 +- + .../include/asm/arch-rockchip/cru_rk322x.h | 1 + + configs/evb-rk3229_defconfig | 2 + + configs/evb-rk3328_defconfig | 2 + + doc/device-tree-bindings/net/phy.txt | 13 + + drivers/clk/rockchip/clk_rk322x.c | 14 +- + drivers/clk/rockchip/clk_rk3328.c | 86 +++++ + drivers/net/gmac_rockchip.c | 341 ++++++++++++++++-- + 9 files changed, 453 insertions(+), 46 deletions(-) +diff --git a/arch/arm/dts/rk3328-u-boot.dtsi b/arch/arm/dts/rk3328-u-boot.dtsi +index 0135bc08d4..27700d156f 100644 +--- a/arch/arm/dts/rk3328-u-boot.dtsi ++++ b/arch/arm/dts/rk3328-u-boot.dtsi +@@ -55,6 +55,11 @@ + bootph-some-ram; + }; + ++&gmac2phy { ++ resets = <&cru SRST_GMAC2PHY_A>, <&cru SRST_MACPHY>; ++ reset-names = "stmmaceth", "mac-phy"; ++}; ++ + &gpio0 { + bootph-pre-ram; + }; +diff --git a/arch/arm/dts/rk3229-evb.dts b/arch/arm/dts/rk3229-evb.dts +index 797476e8be..65fb4f99ec 100644 +--- a/arch/arm/dts/rk3229-evb.dts ++++ b/arch/arm/dts/rk3229-evb.dts +@@ -146,19 +146,25 @@ + }; + + &gmac { +- assigned-clocks = <&cru SCLK_MAC_EXTCLK>, <&cru SCLK_MAC>; +- assigned-clock-parents = <&ext_gmac>, <&cru SCLK_MAC_EXTCLK>; +- clock_in_out = "input"; +- phy-supply = <&vcc_phy>; +- phy-mode = "rgmii"; +- pinctrl-names = "default"; +- pinctrl-0 = <&rgmii_pins>; +- snps,reset-gpio = <&gpio2 RK_PD0 GPIO_ACTIVE_LOW>; +- snps,reset-active-low; +- snps,reset-delays-us = <0 10000 1000000>; +- tx_delay = <0x30>; +- rx_delay = <0x10>; +- status = "okay"; ++ assigned-clocks = <&cru SCLK_MAC_SRC>; ++ assigned-clock-rates = <50000000>; ++ clock_in_out = "output"; ++ phy-supply = <&vcc_phy>; ++ phy-mode = "rmii"; ++ phy-handle = <&phy>; ++ status = "okay"; ++ ++ mdio { ++ compatible = "snps,dwmac-mdio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ phy: phy@0 { ++ compatible = "ethernet-phy-id1234.d400", "ethernet-phy-ieee802.3-c22"; ++ reg = <0>; ++ phy-is-integrated; ++ }; ++ }; + }; + + &io_domains { diff --git a/arch/arm/dts/rk322x.dtsi b/arch/arm/dts/rk322x.dtsi -index 111111111111..222222222222 100644 +index 8eed9e3a92..e3109afa7b 100644 --- a/arch/arm/dts/rk322x.dtsi +++ b/arch/arm/dts/rk322x.dtsi -@@ -878,13 +878,13 @@ +@@ -870,13 +870,13 @@ clocks = <&cru SCLK_MAC>, <&cru SCLK_MAC_RX>, <&cru SCLK_MAC_TX>, <&cru SCLK_MAC_REF>, <&cru SCLK_MAC_REFOUT>, <&cru ACLK_GMAC>, @@ -34,7 +97,7 @@ index 111111111111..222222222222 100644 status = "disabled"; }; diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk322x.h b/arch/arm/include/asm/arch-rockchip/cru_rk322x.h -index 111111111111..222222222222 100644 +index ee12fa831f..cfbc7e92f7 100644 --- a/arch/arm/include/asm/arch-rockchip/cru_rk322x.h +++ b/arch/arm/include/asm/arch-rockchip/cru_rk322x.h @@ -10,6 +10,7 @@ @@ -45,8 +108,34 @@ index 111111111111..222222222222 100644 #define CORE_PERI_HZ 150000000 #define CORE_ACLK_HZ 300000000 +diff --git a/configs/evb-rk3229_defconfig b/configs/evb-rk3229_defconfig +index 3cbc22662a..75726d1283 100644 +--- a/configs/evb-rk3229_defconfig ++++ b/configs/evb-rk3229_defconfig +@@ -62,6 +62,8 @@ CONFIG_GMAC_ROCKCHIP=y + CONFIG_PHY=y + CONFIG_PINCTRL=y + CONFIG_RAM=y ++CONFIG_DM_RESET=y ++CONFIG_RESET_ROCKCHIP=y + CONFIG_SPL_RAM=y + CONFIG_TPL_RAM=y + CONFIG_BAUDRATE=1500000 +diff --git a/configs/evb-rk3328_defconfig b/configs/evb-rk3328_defconfig +index fd52853583..a87179d045 100644 +--- a/configs/evb-rk3328_defconfig ++++ b/configs/evb-rk3328_defconfig +@@ -75,6 +75,8 @@ CONFIG_DM_REGULATOR_FIXED=y + CONFIG_REGULATOR_RK8XX=y + CONFIG_PWM_ROCKCHIP=y + CONFIG_RAM=y ++CONFIG_DM_RESET=y ++CONFIG_RESET_ROCKCHIP=y + CONFIG_SPL_RAM=y + CONFIG_TPL_RAM=y + CONFIG_DM_RNG=y diff --git a/doc/device-tree-bindings/net/phy.txt b/doc/device-tree-bindings/net/phy.txt -index 111111111111..222222222222 100644 +index 6599c667b5..ca1a4a8526 100644 --- a/doc/device-tree-bindings/net/phy.txt +++ b/doc/device-tree-bindings/net/phy.txt @@ -8,6 +8,19 @@ Required properties: @@ -70,10 +159,10 @@ index 111111111111..222222222222 100644 ethernet-phy@0 { diff --git a/drivers/clk/rockchip/clk_rk322x.c b/drivers/clk/rockchip/clk_rk322x.c -index 111111111111..222222222222 100644 +index 9b71fd863b..e97b307bf4 100644 --- a/drivers/clk/rockchip/clk_rk322x.c +++ b/drivers/clk/rockchip/clk_rk322x.c -@@ -42,6 +42,7 @@ enum { +@@ -41,6 +41,7 @@ enum { /* use integer mode*/ static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 3, 1); static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1); @@ -81,7 +170,7 @@ index 111111111111..222222222222 100644 static int rkclk_set_pll(struct rk322x_cru *cru, enum rk_clk_id clk_id, const struct pll_div *div) -@@ -91,11 +92,13 @@ static void rkclk_init(struct rk322x_cru *cru) +@@ -90,11 +91,13 @@ static void rkclk_init(struct rk322x_cru *cru) rk_clrsetreg(&cru->cru_mode_con, GPLL_MODE_MASK | APLL_MODE_MASK, GPLL_MODE_SLOW << GPLL_MODE_SHIFT | @@ -96,7 +185,7 @@ index 111111111111..222222222222 100644 /* * select apll as cpu/core clock pll source and -@@ -168,7 +171,8 @@ static void rkclk_init(struct rk322x_cru *cru) +@@ -167,7 +170,8 @@ static void rkclk_init(struct rk322x_cru *cru) rk_clrsetreg(&cru->cru_mode_con, GPLL_MODE_MASK | APLL_MODE_MASK, GPLL_MODE_NORM << GPLL_MODE_SHIFT | @@ -106,7 +195,7 @@ index 111111111111..222222222222 100644 } /* Get pll rate by id */ -@@ -258,11 +262,10 @@ static ulong rk322x_mac_set_clk(struct rk322x_cru *cru, uint freq) +@@ -257,11 +261,10 @@ static ulong rk322x_mac_set_clk(struct rk322x_cru *cru, uint freq) ulong pll_rate; u8 div; @@ -120,7 +209,7 @@ index 111111111111..222222222222 100644 div = DIV_ROUND_UP(pll_rate, freq) - 1; if (div <= 0x1f) -@@ -461,6 +464,7 @@ static ulong rk322x_clk_set_rate(struct clk *clk, ulong rate) +@@ -390,6 +393,7 @@ static ulong rk322x_clk_set_rate(struct clk *clk, ulong rate) case CLK_DDR: new_rate = rk322x_ddr_set_clk(priv->cru, rate); break; @@ -128,9 +217,133 @@ index 111111111111..222222222222 100644 case SCLK_MAC: new_rate = rk322x_mac_set_clk(priv->cru, rate); break; - +diff --git a/drivers/clk/rockchip/clk_rk3328.c b/drivers/clk/rockchip/clk_rk3328.c +index 7701a9734e..8f05fbe607 100644 +--- a/drivers/clk/rockchip/clk_rk3328.c ++++ b/drivers/clk/rockchip/clk_rk3328.c +@@ -95,6 +95,14 @@ enum { + PCLK_DBG_DIV_SHIFT = 0, + PCLK_DBG_DIV_MASK = 0xF << PCLK_DBG_DIV_SHIFT, + ++ /* CLKSEL_CON26 */ ++ GMAC2PHY_PLL_SEL_SHIFT = 7, ++ GMAC2PHY_PLL_SEL_MASK = 1 << GMAC2PHY_PLL_SEL_SHIFT, ++ GMAC2PHY_PLL_SEL_CPLL = 0, ++ GMAC2PHY_PLL_SEL_GPLL = 1, ++ GMAC2PHY_CLK_DIV_MASK = 0x1f, ++ GMAC2PHY_CLK_DIV_SHIFT = 0, ++ + /* CLKSEL_CON27 */ + GMAC2IO_PLL_SEL_SHIFT = 7, + GMAC2IO_PLL_SEL_MASK = 1 << GMAC2IO_PLL_SEL_SHIFT, +@@ -445,6 +453,39 @@ static ulong rk3328_gmac2io_set_clk(struct rk3328_cru *cru, ulong rate) + return ret; + } + ++static ulong rk3328_gmac2phy_src_set_clk(struct rk3328_cru *cru, ulong rate) ++{ ++ u32 con = readl(&cru->clksel_con[26]); ++ ulong pll_rate; ++ u8 div; ++ ++ if ((con >> GMAC2PHY_PLL_SEL_SHIFT) & GMAC2PHY_PLL_SEL_GPLL) ++ pll_rate = GPLL_HZ; ++ else ++ pll_rate = CPLL_HZ; ++ ++ div = DIV_ROUND_UP(pll_rate, rate) - 1; ++ if (div <= 0x1f) ++ rk_clrsetreg(&cru->clksel_con[26], GMAC2PHY_CLK_DIV_MASK, ++ div << GMAC2PHY_CLK_DIV_SHIFT); ++ else ++ debug("Unsupported div for gmac:%d\n", div); ++ ++ return DIV_TO_RATE(pll_rate, div); ++} ++ ++static ulong rk3328_gmac2phy_set_clk(struct rk3328_cru *cru, ulong rate) ++{ ++ struct rk3328_grf_regs *grf; ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ if (readl(&grf->mac_con[2]) & BIT(10)) ++ /* An external clock will always generate the right rate... */ ++ return rate; ++ else ++ return rk3328_gmac2phy_src_set_clk(cru, rate); ++} ++ + static ulong rk3328_mmc_get_clk(struct rk3328_cru *cru, uint clk_id) + { + u32 div, con, con_id; +@@ -737,6 +778,12 @@ static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate) + case SCLK_MAC2IO: + ret = rk3328_gmac2io_set_clk(priv->cru, rate); + break; ++ case SCLK_MAC2PHY: ++ ret = rk3328_gmac2phy_set_clk(priv->cru, rate); ++ break; ++ case SCLK_MAC2PHY_SRC: ++ ret = rk3328_gmac2phy_src_set_clk(priv->cru, rate); ++ break; + case SCLK_PWM: + ret = rk3328_pwm_set_clk(priv->cru, rate); + break; +@@ -866,6 +913,43 @@ static int rk3328_gmac2io_ext_set_parent(struct clk *clk, struct clk *parent) + return -EINVAL; + } + ++static int rk3328_gmac2phy_set_parent(struct clk *clk, struct clk *parent) ++{ ++ struct rk3328_grf_regs *grf; ++ const char *clock_output_name; ++ int ret; ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ ++ /* ++ * If the requested parent is in the same clock-controller and the id ++ * is SCLK_MAC2PHY_SRC ("clk_mac2phy_src"), switch to the internal clock. ++ */ ++ if ((parent->dev == clk->dev) && (parent->id == SCLK_MAC2PHY_SRC)) { ++ debug("%s: switching MAC CLK to SCLK_MAC2IO_PHY\n", __func__); ++ rk_clrreg(&grf->mac_con[2], BIT(10)); ++ return 0; ++ } ++ ++ /* ++ * Otherwise, we need to check the clock-output-names of the ++ * requested parent to see if the requested id is "phy_50m_out". ++ */ ++ ret = dev_read_string_index(parent->dev, "clock-output-names", ++ parent->id, &clock_output_name); ++ if (ret < 0) ++ return -ENODATA; ++ ++ /* If this is "phy_50m_out", switch to the external clock input */ ++ if (!strcmp(clock_output_name, "phy_50m_out")) { ++ debug("%s: switching MAC CLK to PHY_50M_OUT\n", __func__); ++ rk_setreg(&grf->mac_con[2], BIT(10)); ++ return 0; ++ } ++ ++ return -EINVAL; ++} ++ + static int rk3328_clk_set_parent(struct clk *clk, struct clk *parent) + { + switch (clk->id) { +@@ -873,6 +957,8 @@ static int rk3328_clk_set_parent(struct clk *clk, struct clk *parent) + return rk3328_gmac2io_set_parent(clk, parent); + case SCLK_MAC2IO_EXT: + return rk3328_gmac2io_ext_set_parent(clk, parent); ++ case SCLK_MAC2PHY: ++ return rk3328_gmac2phy_set_parent(clk, parent); + case DCLK_LCDC: + case USB480M: + case SCLK_PDM: diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c -index 8cfeeffe95..c215b1b3f4 100644 +index 8cfeeffe95..2b8f1245eb 100644 --- a/drivers/net/gmac_rockchip.c +++ b/drivers/net/gmac_rockchip.c @@ -10,6 +10,7 @@ @@ -150,7 +363,7 @@ index 8cfeeffe95..c215b1b3f4 100644 #include #include #include "designware.h" -@@ -41,20 +44,29 @@ DECLARE_GLOBAL_DATA_PTR; +@@ -41,20 +44,28 @@ DECLARE_GLOBAL_DATA_PTR; struct gmac_rockchip_plat { struct dw_eth_pdata dw_eth_pdata; bool clock_input; @@ -161,11 +374,11 @@ index 8cfeeffe95..c215b1b3f4 100644 }; struct rk_gmac_ops { - int (*fix_mac_speed)(struct dw_eth_dev *priv); +- int (*fix_mac_speed)(struct dw_eth_dev *priv); + int (*fix_rmii_speed)(struct gmac_rockchip_plat *pdata, -+ struct dw_eth_dev *priv); ++ struct dw_eth_dev *priv); + int (*fix_rgmii_speed)(struct gmac_rockchip_plat *pdata, -+ struct dw_eth_dev *priv); ++ struct dw_eth_dev *priv); void (*set_to_rmii)(struct gmac_rockchip_plat *pdata); void (*set_to_rgmii)(struct gmac_rockchip_plat *pdata); + void (*integrated_phy_powerup)(struct gmac_rockchip_plat *pdata); @@ -180,7 +393,7 @@ index 8cfeeffe95..c215b1b3f4 100644 string = dev_read_string(dev, "clock_in_out"); if (!strcmp(string, "input")) -@@ -62,6 +74,25 @@ static int gmac_rockchip_of_to_plat(struct udevice *dev) +@@ -62,6 +73,25 @@ static int gmac_rockchip_of_to_plat(struct udevice *dev) else pdata->clock_input = false; @@ -206,6 +419,16 @@ index 8cfeeffe95..c215b1b3f4 100644 /* Check the new naming-style first... */ pdata->tx_delay = dev_read_u32_default(dev, "tx_delay", -ENOENT); pdata->rx_delay = dev_read_u32_default(dev, "rx_delay", -ENOENT); +@@ -75,7 +105,8 @@ static int gmac_rockchip_of_to_plat(struct udevice *dev) + return designware_eth_of_to_plat(dev); + } + +-static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int px30_gmac_fix_rmii_speed(struct gmac_rockchip_plat *pdata, ++ struct dw_eth_dev *priv) + { + struct px30_grf *grf; + struct clk clk_speed; @@ -116,7 +147,43 @@ static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; } @@ -251,36 +474,157 @@ index 8cfeeffe95..c215b1b3f4 100644 { struct rk322x_grf *grf; int clk; -@@ -358,6 +425,28 @@ static void px30_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata) +@@ -149,7 +216,8 @@ static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int rk3288_gmac_fix_rgmii_speed(struct gmac_rockchip_plat *pdata, ++ struct dw_eth_dev *priv) + { + struct rk3288_grf *grf; + int clk; +@@ -175,7 +243,8 @@ static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int rk3308_gmac_fix_rmii_speed(struct gmac_rockchip_plat *pdata, ++ struct dw_eth_dev *priv) + { + struct rk3308_grf *grf; + struct clk clk_speed; +@@ -216,7 +285,43 @@ static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int rk3328_gmac_fix_rmii_speed(struct gmac_rockchip_plat *pdata, ++ struct dw_eth_dev *priv) ++{ ++ struct rk3328_grf_regs *grf; ++ int clk; ++ enum { ++ RK3328_GMAC_RMII_CLK_MASK = BIT(7), ++ RK3328_GMAC_RMII_CLK_2_5M = 0, ++ RK3328_GMAC_RMII_CLK_25M = BIT(7), ++ ++ RK3328_GMAC_RMII_SPEED_MASK = BIT(2), ++ RK3328_GMAC_RMII_SPEED_10 = 0, ++ RK3328_GMAC_RMII_SPEED_100 = BIT(2), ++ }; ++ ++ switch (priv->phydev->speed) { ++ case 10: ++ clk = RK3328_GMAC_RMII_CLK_2_5M | RK3328_GMAC_RMII_SPEED_10; ++ break; ++ case 100: ++ clk = RK3328_GMAC_RMII_CLK_25M | RK3328_GMAC_RMII_SPEED_100; ++ break; ++ default: ++ debug("Unknown phy speed: %d\n", priv->phydev->speed); ++ return -EINVAL; ++ } ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ rk_clrsetreg(pdata->integrated_phy ? &grf->mac_con[2] : &grf->mac_con[1], ++ RK3328_GMAC_RMII_CLK_MASK | RK3328_GMAC_RMII_SPEED_MASK, ++ clk); ++ ++ return 0; ++} ++ ++static int rk3328_gmac_fix_rgmii_speed(struct gmac_rockchip_plat *pdata, ++ struct dw_eth_dev *priv) + { + struct rk3328_grf_regs *grf; + int clk; +@@ -249,7 +354,8 @@ static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int rk3368_gmac_fix_rgmii_speed(struct gmac_rockchip_plat *pdata, ++ struct dw_eth_dev *priv) + { + struct rk3368_grf *grf; + int clk; +@@ -281,7 +387,8 @@ static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv) ++static int rk3399_gmac_fix_rgmii_speed(struct gmac_rockchip_plat *pdata, ++ struct dw_eth_dev *priv) + { + struct rk3399_grf_regs *grf; + int clk; +@@ -307,7 +414,8 @@ static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv) + return 0; + } + +-static int rv1108_set_rmii_speed(struct dw_eth_dev *priv) ++static int rv1108_gmac_fix_rmii_speed(struct gmac_rockchip_plat *pdata, ++ struct dw_eth_dev *priv) + { + struct rv1108_grf *grf; + int clk, speed; +@@ -358,6 +466,28 @@ static void px30_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata) PX30_GMAC_PHY_INTF_SEL_RMII); } +static void rk3228_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata) +{ -+ struct rk322x_grf *grf; -+ enum { -+ RK3228_GRF_CON_RMII_MODE_MASK = BIT(11), -+ RK3228_GRF_CON_RMII_MODE_SEL = BIT(11), -+ RK3228_RMII_MODE_MASK = BIT(10), -+ RK3228_RMII_MODE_SEL = BIT(10), -+ RK3228_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4), -+ RK3228_GMAC_PHY_INTF_SEL_RMII = BIT(6), -+ }; ++ struct rk322x_grf *grf; ++ enum { ++ RK3228_GRF_CON_RMII_MODE_MASK = BIT(11), ++ RK3228_GRF_CON_RMII_MODE_SEL = BIT(11), ++ RK3228_RMII_MODE_MASK = BIT(10), ++ RK3228_RMII_MODE_SEL = BIT(10), ++ RK3228_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4), ++ RK3228_GMAC_PHY_INTF_SEL_RMII = BIT(6), ++ }; + -+ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); -+ rk_clrsetreg(&grf->mac_con[1], -+ RK3228_GRF_CON_RMII_MODE_MASK | -+ RK3228_RMII_MODE_MASK | -+ RK3228_GMAC_PHY_INTF_SEL_MASK, -+ RK3228_GRF_CON_RMII_MODE_SEL | -+ RK3228_RMII_MODE_SEL | -+ RK3228_GMAC_PHY_INTF_SEL_RMII); ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ rk_clrsetreg(&grf->mac_con[1], ++ RK3228_GRF_CON_RMII_MODE_MASK | ++ RK3228_RMII_MODE_MASK | ++ RK3228_GMAC_PHY_INTF_SEL_MASK, ++ RK3228_GRF_CON_RMII_MODE_SEL | ++ RK3228_RMII_MODE_SEL | ++ RK3228_GMAC_PHY_INTF_SEL_RMII); +} + static void rk3228_gmac_set_to_rgmii(struct gmac_rockchip_plat *pdata) { struct rk322x_grf *grf; -@@ -551,6 +640,66 @@ static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata) +@@ -436,6 +566,25 @@ static void rk3308_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata) + RK3308_GMAC_PHY_INTF_SEL_RMII); + } + ++static void rk3328_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata) ++{ ++ struct rk3328_grf_regs *grf; ++ enum { ++ RK3328_RMII_MODE_MASK = BIT(9), ++ RK3328_RMII_MODE = BIT(9), ++ ++ RK3328_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4), ++ RK3328_GMAC_PHY_INTF_SEL_RMII = BIT(6), ++ }; ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ rk_clrsetreg(pdata->integrated_phy ? &grf->mac_con[2] : &grf->mac_con[1], ++ RK3328_RMII_MODE_MASK | ++ RK3328_GMAC_PHY_INTF_SEL_MASK, ++ RK3328_GMAC_PHY_INTF_SEL_RMII | ++ RK3328_RMII_MODE); ++} ++ + static void rk3328_gmac_set_to_rgmii(struct gmac_rockchip_plat *pdata) + { + struct rk3328_grf_regs *grf; +@@ -551,6 +700,126 @@ static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata) RV1108_GMAC_PHY_INTF_SEL_RMII); } @@ -343,11 +687,71 @@ index 8cfeeffe95..c215b1b3f4 100644 + RK3228_MACPHY_ENABLE); + udelay(30 * 1000); +} ++ ++static void rk3328_gmac_integrated_phy_powerup(struct gmac_rockchip_plat *pdata) ++{ ++ struct rk3328_grf_regs *grf; ++ enum { ++ RK3328_GRF_CON_RMII_MODE_MASK = BIT(9), ++ RK3328_GRF_CON_RMII_MODE = BIT(9), ++ }; ++ enum { ++ RK3328_MACPHY_CFG_CLK_50M_MASK = BIT(14), ++ RK3328_MACPHY_CFG_CLK_50M = BIT(14), ++ ++ RK3328_MACPHY_RMII_MODE_MASK = GENMASK(7, 6), ++ RK3328_MACPHY_RMII_MODE = BIT(6), ++ ++ RK3328_MACPHY_ENABLE_MASK = BIT(0), ++ RK3328_MACPHY_DISENABLE = 0, ++ RK3328_MACPHY_ENABLE = BIT(0), ++ }; ++ enum { ++ RK3328_RK_GRF_CON2_MACPHY_ID_MASK = GENMASK(6, 0), ++ RK3328_RK_GRF_CON2_MACPHY_ID = 0x1234, ++ }; ++ enum { ++ RK3328_RK_GRF_CON3_MACPHY_ID_MASK = GENMASK(5, 0), ++ RK3328_RK_GRF_CON3_MACPHY_ID = 0x35, ++ }; ++ ++ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); ++ rk_clrsetreg(&grf->macphy_con[1], ++ RK3328_GRF_CON_RMII_MODE_MASK, ++ RK3328_GRF_CON_RMII_MODE); ++ ++ rk_clrsetreg(&grf->macphy_con[2], ++ RK3328_RK_GRF_CON2_MACPHY_ID_MASK, ++ RK3328_RK_GRF_CON2_MACPHY_ID); ++ ++ rk_clrsetreg(&grf->macphy_con[3], ++ RK3328_RK_GRF_CON3_MACPHY_ID_MASK, ++ RK3328_RK_GRF_CON3_MACPHY_ID); ++ ++ /* disabled before trying to reset it */ ++ rk_clrsetreg(&grf->macphy_con[0], ++ RK3328_MACPHY_CFG_CLK_50M_MASK | ++ RK3328_MACPHY_RMII_MODE_MASK | ++ RK3328_MACPHY_ENABLE_MASK, ++ RK3328_MACPHY_CFG_CLK_50M | ++ RK3328_MACPHY_RMII_MODE | ++ RK3328_MACPHY_DISENABLE); ++ ++ reset_assert(&pdata->phy_reset); ++ udelay(10); ++ reset_deassert(&pdata->phy_reset); ++ udelay(10); ++ ++ rk_clrsetreg(&grf->macphy_con[0], ++ RK3328_MACPHY_ENABLE_MASK, ++ RK3328_MACPHY_ENABLE); ++ udelay(30 * 1000); ++} + static int gmac_rockchip_probe(struct udevice *dev) { struct gmac_rockchip_plat *pdata = dev_get_plat(dev); -@@ -570,6 +719,9 @@ static int gmac_rockchip_probe(struct udevice *dev) +@@ -570,6 +839,9 @@ static int gmac_rockchip_probe(struct udevice *dev) if (ret) return ret; @@ -357,7 +761,16 @@ index 8cfeeffe95..c215b1b3f4 100644 switch (eth_pdata->phy_interface) { case PHY_INTERFACE_MODE_RGMII: /* Set to RGMII mode */ -@@ -653,7 +805,7 @@ static int gmac_rockchip_probe(struct udevice *dev) +@@ -617,7 +889,7 @@ static int gmac_rockchip_probe(struct udevice *dev) + + if (!pdata->clock_input) { + rate = clk_set_rate(&clk, 50000000); +- if (rate != 50000000) ++ if (rate != 50000000 && rate != 49500000) + return -EINVAL; + } + break; +@@ -653,7 +925,7 @@ static int gmac_rockchip_probe(struct udevice *dev) break; default: @@ -366,7 +779,7 @@ index 8cfeeffe95..c215b1b3f4 100644 return -ENXIO; } -@@ -662,18 +814,33 @@ static int gmac_rockchip_probe(struct udevice *dev) +@@ -662,18 +934,33 @@ static int gmac_rockchip_probe(struct udevice *dev) static int gmac_rockchip_eth_start(struct udevice *dev) { @@ -387,25 +800,31 @@ index 8cfeeffe95..c215b1b3f4 100644 return ret; + + switch (eth_pdata->phy_interface) { -+ case PHY_INTERFACE_MODE_RGMII: -+ ret = ops->fix_rgmii_speed(pdata, priv); -+ if (ret) -+ return ret; -+ break; -+ case PHY_INTERFACE_MODE_RMII: -+ ret = ops->fix_rmii_speed(pdata, priv); -+ if (ret) -+ return ret; -+ break; -+ default: -+ debug("%s: no interface defined!\n", __func__); -+ return -ENXIO; ++ case PHY_INTERFACE_MODE_RGMII: ++ ret = ops->fix_rgmii_speed(pdata, priv); ++ if (ret) ++ return ret; ++ break; ++ case PHY_INTERFACE_MODE_RMII: ++ ret = ops->fix_rmii_speed(pdata, priv); ++ if (ret) ++ return ret; ++ break; ++ default: ++ debug("%s: no interface defined!\n", __func__); ++ return -ENXIO; + } + ret = designware_eth_enable(priv); if (ret) return ret; -@@ -696,8 +863,11 @@ const struct rk_gmac_ops px30_gmac_ops = { +@@ -691,42 +978,48 @@ const struct eth_ops gmac_rockchip_eth_ops = { + }; + + const struct rk_gmac_ops px30_gmac_ops = { +- .fix_mac_speed = px30_gmac_fix_mac_speed, ++ .fix_rmii_speed = px30_gmac_fix_rmii_speed, + .set_to_rmii = px30_gmac_set_to_rmii, }; const struct rk_gmac_ops rk3228_gmac_ops = { @@ -418,3 +837,45 @@ index 8cfeeffe95..c215b1b3f4 100644 }; const struct rk_gmac_ops rk3288_gmac_ops = { +- .fix_mac_speed = rk3288_gmac_fix_mac_speed, ++ .fix_rgmii_speed = rk3288_gmac_fix_rgmii_speed, + .set_to_rgmii = rk3288_gmac_set_to_rgmii, + }; + + const struct rk_gmac_ops rk3308_gmac_ops = { +- .fix_mac_speed = rk3308_gmac_fix_mac_speed, ++ .fix_rmii_speed = rk3308_gmac_fix_rmii_speed, + .set_to_rmii = rk3308_gmac_set_to_rmii, + }; + + const struct rk_gmac_ops rk3328_gmac_ops = { +- .fix_mac_speed = rk3328_gmac_fix_mac_speed, ++ .fix_rmii_speed = rk3328_gmac_fix_rmii_speed, ++ .fix_rgmii_speed = rk3328_gmac_fix_rgmii_speed, ++ .set_to_rmii = rk3328_gmac_set_to_rmii, + .set_to_rgmii = rk3328_gmac_set_to_rgmii, ++ .integrated_phy_powerup = rk3328_gmac_integrated_phy_powerup, + }; + + const struct rk_gmac_ops rk3368_gmac_ops = { +- .fix_mac_speed = rk3368_gmac_fix_mac_speed, ++ .fix_rgmii_speed = rk3368_gmac_fix_rgmii_speed, + .set_to_rgmii = rk3368_gmac_set_to_rgmii, + }; + + const struct rk_gmac_ops rk3399_gmac_ops = { +- .fix_mac_speed = rk3399_gmac_fix_mac_speed, ++ .fix_rgmii_speed = rk3399_gmac_fix_rgmii_speed, + .set_to_rgmii = rk3399_gmac_set_to_rgmii, + }; + + const struct rk_gmac_ops rv1108_gmac_ops = { +- .fix_mac_speed = rv1108_set_rmii_speed, ++ .fix_rmii_speed = rv1108_gmac_fix_rmii_speed, + .set_to_rmii = rv1108_gmac_set_to_rmii, + }; + +-- +2.43.0 + +