@@ -61,6 +61,7 @@ struct rk_priv_data {
6161 struct clk * mac_clk_tx ;
6262 struct clk * clk_mac_ref ;
6363 struct clk * clk_mac_refout ;
64+ struct clk * clk_mac_speed ;
6465 struct clk * aclk_mac ;
6566 struct clk * pclk_mac ;
6667 struct clk * clk_phy ;
@@ -83,6 +84,64 @@ struct rk_priv_data {
8384 (((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \
8485 ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE))
8586
87+ #define PX30_GRF_GMAC_CON1 0x0904
88+
89+ /* PX30_GRF_GMAC_CON1 */
90+ #define PX30_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \
91+ GRF_BIT(6))
92+ #define PX30_GMAC_SPEED_10M GRF_CLR_BIT(2)
93+ #define PX30_GMAC_SPEED_100M GRF_BIT(2)
94+
95+ static void px30_set_to_rmii (struct rk_priv_data * bsp_priv )
96+ {
97+ struct device * dev = & bsp_priv -> pdev -> dev ;
98+
99+ if (IS_ERR (bsp_priv -> grf )) {
100+ dev_err (dev , "%s: Missing rockchip,grf property\n" , __func__ );
101+ return ;
102+ }
103+
104+ regmap_write (bsp_priv -> grf , PX30_GRF_GMAC_CON1 ,
105+ PX30_GMAC_PHY_INTF_SEL_RMII );
106+ }
107+
108+ static void px30_set_rmii_speed (struct rk_priv_data * bsp_priv , int speed )
109+ {
110+ struct device * dev = & bsp_priv -> pdev -> dev ;
111+ int ret ;
112+
113+ if (IS_ERR (bsp_priv -> clk_mac_speed )) {
114+ dev_err (dev , "%s: Missing clk_mac_speed clock\n" , __func__ );
115+ return ;
116+ }
117+
118+ if (speed == 10 ) {
119+ regmap_write (bsp_priv -> grf , PX30_GRF_GMAC_CON1 ,
120+ PX30_GMAC_SPEED_10M );
121+
122+ ret = clk_set_rate (bsp_priv -> clk_mac_speed , 2500000 );
123+ if (ret )
124+ dev_err (dev , "%s: set clk_mac_speed rate 2500000 failed: %d\n" ,
125+ __func__ , ret );
126+ } else if (speed == 100 ) {
127+ regmap_write (bsp_priv -> grf , PX30_GRF_GMAC_CON1 ,
128+ PX30_GMAC_SPEED_100M );
129+
130+ ret = clk_set_rate (bsp_priv -> clk_mac_speed , 25000000 );
131+ if (ret )
132+ dev_err (dev , "%s: set clk_mac_speed rate 25000000 failed: %d\n" ,
133+ __func__ , ret );
134+
135+ } else {
136+ dev_err (dev , "unknown speed value for RMII! speed=%d" , speed );
137+ }
138+ }
139+
140+ static const struct rk_gmac_ops px30_ops = {
141+ .set_to_rmii = px30_set_to_rmii ,
142+ .set_rmii_speed = px30_set_rmii_speed ,
143+ };
144+
86145#define RK3128_GRF_MAC_CON0 0x0168
87146#define RK3128_GRF_MAC_CON1 0x016c
88147
@@ -1042,6 +1101,10 @@ static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat)
10421101 }
10431102 }
10441103
1104+ bsp_priv -> clk_mac_speed = devm_clk_get (dev , "clk_mac_speed" );
1105+ if (IS_ERR (bsp_priv -> clk_mac_speed ))
1106+ dev_err (dev , "cannot get clock %s\n" , "clk_mac_speed" );
1107+
10451108 if (bsp_priv -> clock_input ) {
10461109 dev_info (dev , "clock input from PHY\n" );
10471110 } else {
@@ -1094,6 +1157,9 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
10941157 if (!IS_ERR (bsp_priv -> mac_clk_tx ))
10951158 clk_prepare_enable (bsp_priv -> mac_clk_tx );
10961159
1160+ if (!IS_ERR (bsp_priv -> clk_mac_speed ))
1161+ clk_prepare_enable (bsp_priv -> clk_mac_speed );
1162+
10971163 /**
10981164 * if (!IS_ERR(bsp_priv->clk_mac))
10991165 * clk_prepare_enable(bsp_priv->clk_mac);
@@ -1118,6 +1184,8 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
11181184 clk_disable_unprepare (bsp_priv -> pclk_mac );
11191185
11201186 clk_disable_unprepare (bsp_priv -> mac_clk_tx );
1187+
1188+ clk_disable_unprepare (bsp_priv -> clk_mac_speed );
11211189 /**
11221190 * if (!IS_ERR(bsp_priv->clk_mac))
11231191 * clk_disable_unprepare(bsp_priv->clk_mac);
@@ -1414,6 +1482,7 @@ static int rk_gmac_resume(struct device *dev)
14141482static SIMPLE_DEV_PM_OPS (rk_gmac_pm_ops , rk_gmac_suspend , rk_gmac_resume ) ;
14151483
14161484static const struct of_device_id rk_gmac_dwmac_match [] = {
1485+ { .compatible = "rockchip,px30-gmac" , .data = & px30_ops },
14171486 { .compatible = "rockchip,rk3128-gmac" , .data = & rk3128_ops },
14181487 { .compatible = "rockchip,rk3228-gmac" , .data = & rk3228_ops },
14191488 { .compatible = "rockchip,rk3288-gmac" , .data = & rk3288_ops },
0 commit comments