1 /* 2 * (C) Copyright 2015 Sjoerd Simons <sjoerd.simons@collabora.co.uk> 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 * 6 * Rockchip GMAC ethernet IP driver for U-Boot 7 */ 8 9 #include <common.h> 10 #include <dm.h> 11 #include <clk.h> 12 #include <phy.h> 13 #include <syscon.h> 14 #include <asm/io.h> 15 #include <asm/arch/periph.h> 16 #include <asm/arch/clock.h> 17 #include <asm/arch/hardware.h> 18 #include <asm/arch/grf_rk3288.h> 19 #include <asm/arch/grf_rk3368.h> 20 #include <asm/arch/grf_rk3399.h> 21 #include <asm/arch/grf_rv1108.h> 22 #include <dm/pinctrl.h> 23 #include <dt-bindings/clock/rk3288-cru.h> 24 #include "designware.h" 25 26 DECLARE_GLOBAL_DATA_PTR; 27 28 /* 29 * Platform data for the gmac 30 * 31 * dw_eth_pdata: Required platform data for designware driver (must be first) 32 */ 33 struct gmac_rockchip_platdata { 34 struct dw_eth_pdata dw_eth_pdata; 35 bool clock_input; 36 int tx_delay; 37 int rx_delay; 38 }; 39 40 struct rk_gmac_ops { 41 int (*fix_mac_speed)(struct dw_eth_dev *priv); 42 void (*set_to_rmii)(struct gmac_rockchip_platdata *pdata); 43 void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata); 44 }; 45 46 47 static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) 48 { 49 struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); 50 const char *string; 51 52 string = dev_read_string(dev, "clock_in_out"); 53 if (!strcmp(string, "input")) 54 pdata->clock_input = true; 55 else 56 pdata->clock_input = false; 57 58 /* Check the new naming-style first... */ 59 pdata->tx_delay = dev_read_u32_default(dev, "tx_delay", -ENOENT); 60 pdata->rx_delay = dev_read_u32_default(dev, "rx_delay", -ENOENT); 61 62 /* ... and fall back to the old naming style or default, if necessary */ 63 if (pdata->tx_delay == -ENOENT) 64 pdata->tx_delay = dev_read_u32_default(dev, "tx-delay", 0x30); 65 if (pdata->rx_delay == -ENOENT) 66 pdata->rx_delay = dev_read_u32_default(dev, "rx-delay", 0x10); 67 68 return designware_eth_ofdata_to_platdata(dev); 69 } 70 71 static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) 72 { 73 struct rk3288_grf *grf; 74 int clk; 75 76 switch (priv->phydev->speed) { 77 case 10: 78 clk = RK3288_GMAC_CLK_SEL_2_5M; 79 break; 80 case 100: 81 clk = RK3288_GMAC_CLK_SEL_25M; 82 break; 83 case 1000: 84 clk = RK3288_GMAC_CLK_SEL_125M; 85 break; 86 default: 87 debug("Unknown phy speed: %d\n", priv->phydev->speed); 88 return -EINVAL; 89 } 90 91 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 92 rk_clrsetreg(&grf->soc_con1, RK3288_GMAC_CLK_SEL_MASK, clk); 93 94 return 0; 95 } 96 97 static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv) 98 { 99 struct rk3368_grf *grf; 100 int clk; 101 enum { 102 RK3368_GMAC_CLK_SEL_2_5M = 2 << 4, 103 RK3368_GMAC_CLK_SEL_25M = 3 << 4, 104 RK3368_GMAC_CLK_SEL_125M = 0 << 4, 105 RK3368_GMAC_CLK_SEL_MASK = GENMASK(5, 4), 106 }; 107 108 switch (priv->phydev->speed) { 109 case 10: 110 clk = RK3368_GMAC_CLK_SEL_2_5M; 111 break; 112 case 100: 113 clk = RK3368_GMAC_CLK_SEL_25M; 114 break; 115 case 1000: 116 clk = RK3368_GMAC_CLK_SEL_125M; 117 break; 118 default: 119 debug("Unknown phy speed: %d\n", priv->phydev->speed); 120 return -EINVAL; 121 } 122 123 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 124 rk_clrsetreg(&grf->soc_con15, RK3368_GMAC_CLK_SEL_MASK, clk); 125 126 return 0; 127 } 128 129 static int rk3399_gmac_fix_mac_speed(struct dw_eth_dev *priv) 130 { 131 struct rk3399_grf_regs *grf; 132 int clk; 133 134 switch (priv->phydev->speed) { 135 case 10: 136 clk = RK3399_GMAC_CLK_SEL_2_5M; 137 break; 138 case 100: 139 clk = RK3399_GMAC_CLK_SEL_25M; 140 break; 141 case 1000: 142 clk = RK3399_GMAC_CLK_SEL_125M; 143 break; 144 default: 145 debug("Unknown phy speed: %d\n", priv->phydev->speed); 146 return -EINVAL; 147 } 148 149 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 150 rk_clrsetreg(&grf->soc_con5, RK3399_GMAC_CLK_SEL_MASK, clk); 151 152 return 0; 153 } 154 155 static int rv1108_set_rmii_speed(struct dw_eth_dev *priv) 156 { 157 struct rv1108_grf *grf; 158 int clk, speed; 159 enum { 160 RV1108_GMAC_SPEED_MASK = BIT(2), 161 RV1108_GMAC_SPEED_10M = 0 << 2, 162 RV1108_GMAC_SPEED_100M = 1 << 2, 163 RV1108_GMAC_CLK_SEL_MASK = BIT(7), 164 RV1108_GMAC_CLK_SEL_2_5M = 0 << 7, 165 RV1108_GMAC_CLK_SEL_25M = 1 << 7, 166 }; 167 168 switch (priv->phydev->speed) { 169 case 10: 170 clk = RV1108_GMAC_CLK_SEL_2_5M; 171 speed = RV1108_GMAC_SPEED_10M; 172 break; 173 case 100: 174 clk = RV1108_GMAC_CLK_SEL_25M; 175 speed = RV1108_GMAC_SPEED_100M; 176 break; 177 default: 178 debug("Unknown phy speed: %d\n", priv->phydev->speed); 179 return -EINVAL; 180 } 181 182 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 183 rk_clrsetreg(&grf->gmac_con0, 184 RV1108_GMAC_CLK_SEL_MASK | RV1108_GMAC_SPEED_MASK, 185 clk | speed); 186 187 return 0; 188 } 189 190 static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) 191 { 192 struct rk3288_grf *grf; 193 194 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 195 rk_clrsetreg(&grf->soc_con1, 196 RK3288_RMII_MODE_MASK | RK3288_GMAC_PHY_INTF_SEL_MASK, 197 RK3288_GMAC_PHY_INTF_SEL_RGMII); 198 199 rk_clrsetreg(&grf->soc_con3, 200 RK3288_RXCLK_DLY_ENA_GMAC_MASK | 201 RK3288_TXCLK_DLY_ENA_GMAC_MASK | 202 RK3288_CLK_RX_DL_CFG_GMAC_MASK | 203 RK3288_CLK_TX_DL_CFG_GMAC_MASK, 204 RK3288_RXCLK_DLY_ENA_GMAC_ENABLE | 205 RK3288_TXCLK_DLY_ENA_GMAC_ENABLE | 206 pdata->rx_delay << RK3288_CLK_RX_DL_CFG_GMAC_SHIFT | 207 pdata->tx_delay << RK3288_CLK_TX_DL_CFG_GMAC_SHIFT); 208 } 209 210 static void rk3368_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) 211 { 212 struct rk3368_grf *grf; 213 enum { 214 RK3368_GMAC_PHY_INTF_SEL_RGMII = 1 << 9, 215 RK3368_GMAC_PHY_INTF_SEL_MASK = GENMASK(11, 9), 216 RK3368_RMII_MODE_MASK = BIT(6), 217 RK3368_RMII_MODE = BIT(6), 218 }; 219 enum { 220 RK3368_RXCLK_DLY_ENA_GMAC_MASK = BIT(15), 221 RK3368_RXCLK_DLY_ENA_GMAC_DISABLE = 0, 222 RK3368_RXCLK_DLY_ENA_GMAC_ENABLE = BIT(15), 223 RK3368_TXCLK_DLY_ENA_GMAC_MASK = BIT(7), 224 RK3368_TXCLK_DLY_ENA_GMAC_DISABLE = 0, 225 RK3368_TXCLK_DLY_ENA_GMAC_ENABLE = BIT(7), 226 RK3368_CLK_RX_DL_CFG_GMAC_SHIFT = 8, 227 RK3368_CLK_RX_DL_CFG_GMAC_MASK = GENMASK(14, 8), 228 RK3368_CLK_TX_DL_CFG_GMAC_SHIFT = 0, 229 RK3368_CLK_TX_DL_CFG_GMAC_MASK = GENMASK(6, 0), 230 }; 231 232 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 233 rk_clrsetreg(&grf->soc_con15, 234 RK3368_RMII_MODE_MASK | RK3368_GMAC_PHY_INTF_SEL_MASK, 235 RK3368_GMAC_PHY_INTF_SEL_RGMII); 236 237 rk_clrsetreg(&grf->soc_con16, 238 RK3368_RXCLK_DLY_ENA_GMAC_MASK | 239 RK3368_TXCLK_DLY_ENA_GMAC_MASK | 240 RK3368_CLK_RX_DL_CFG_GMAC_MASK | 241 RK3368_CLK_TX_DL_CFG_GMAC_MASK, 242 RK3368_RXCLK_DLY_ENA_GMAC_ENABLE | 243 RK3368_TXCLK_DLY_ENA_GMAC_ENABLE | 244 pdata->rx_delay << RK3368_CLK_RX_DL_CFG_GMAC_SHIFT | 245 pdata->tx_delay << RK3368_CLK_TX_DL_CFG_GMAC_SHIFT); 246 } 247 248 static void rk3399_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) 249 { 250 struct rk3399_grf_regs *grf; 251 252 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 253 254 rk_clrsetreg(&grf->soc_con5, 255 RK3399_GMAC_PHY_INTF_SEL_MASK, 256 RK3399_GMAC_PHY_INTF_SEL_RGMII); 257 258 rk_clrsetreg(&grf->soc_con6, 259 RK3399_RXCLK_DLY_ENA_GMAC_MASK | 260 RK3399_TXCLK_DLY_ENA_GMAC_MASK | 261 RK3399_CLK_RX_DL_CFG_GMAC_MASK | 262 RK3399_CLK_TX_DL_CFG_GMAC_MASK, 263 RK3399_RXCLK_DLY_ENA_GMAC_ENABLE | 264 RK3399_TXCLK_DLY_ENA_GMAC_ENABLE | 265 pdata->rx_delay << RK3399_CLK_RX_DL_CFG_GMAC_SHIFT | 266 pdata->tx_delay << RK3399_CLK_TX_DL_CFG_GMAC_SHIFT); 267 } 268 269 static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata) 270 { 271 struct rv1108_grf *grf; 272 273 enum { 274 RV1108_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4), 275 RV1108_GMAC_PHY_INTF_SEL_RMII = 4 << 4, 276 }; 277 278 grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 279 rk_clrsetreg(&grf->gmac_con0, 280 RV1108_GMAC_PHY_INTF_SEL_MASK, 281 RV1108_GMAC_PHY_INTF_SEL_RMII); 282 } 283 284 static int gmac_rockchip_probe(struct udevice *dev) 285 { 286 struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); 287 struct rk_gmac_ops *ops = 288 (struct rk_gmac_ops *)dev_get_driver_data(dev); 289 struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev); 290 struct eth_pdata *eth_pdata = &dw_pdata->eth_pdata; 291 struct clk clk; 292 ulong rate; 293 int ret; 294 295 ret = clk_get_by_index(dev, 0, &clk); 296 if (ret) 297 return ret; 298 299 switch (eth_pdata->phy_interface) { 300 case PHY_INTERFACE_MODE_RGMII: 301 /* 302 * If the gmac clock is from internal pll, need to set and 303 * check the return value for gmac clock at RGMII mode. If 304 * the gmac clock is from external source, the clock rate 305 * is not set, because of it is bypassed. 306 */ 307 if (!pdata->clock_input) { 308 rate = clk_set_rate(&clk, 125000000); 309 if (rate != 125000000) 310 return -EINVAL; 311 } 312 313 /* Set to RGMII mode */ 314 if (ops->set_to_rgmii) 315 ops->set_to_rgmii(pdata); 316 else 317 return -EPERM; 318 319 break; 320 case PHY_INTERFACE_MODE_RMII: 321 /* The commet is the same as RGMII mode */ 322 if (!pdata->clock_input) { 323 rate = clk_set_rate(&clk, 50000000); 324 if (rate != 50000000) 325 return -EINVAL; 326 } 327 328 /* Set to RMII mode */ 329 if (ops->set_to_rmii) 330 ops->set_to_rmii(pdata); 331 else 332 return -EPERM; 333 334 break; 335 default: 336 debug("NO interface defined!\n"); 337 return -ENXIO; 338 } 339 340 return designware_eth_probe(dev); 341 } 342 343 static int gmac_rockchip_eth_start(struct udevice *dev) 344 { 345 struct eth_pdata *pdata = dev_get_platdata(dev); 346 struct dw_eth_dev *priv = dev_get_priv(dev); 347 struct rk_gmac_ops *ops = 348 (struct rk_gmac_ops *)dev_get_driver_data(dev); 349 int ret; 350 351 ret = designware_eth_init(priv, pdata->enetaddr); 352 if (ret) 353 return ret; 354 ret = ops->fix_mac_speed(priv); 355 if (ret) 356 return ret; 357 ret = designware_eth_enable(priv); 358 if (ret) 359 return ret; 360 361 return 0; 362 } 363 364 const struct eth_ops gmac_rockchip_eth_ops = { 365 .start = gmac_rockchip_eth_start, 366 .send = designware_eth_send, 367 .recv = designware_eth_recv, 368 .free_pkt = designware_eth_free_pkt, 369 .stop = designware_eth_stop, 370 .write_hwaddr = designware_eth_write_hwaddr, 371 }; 372 373 const struct rk_gmac_ops rk3288_gmac_ops = { 374 .fix_mac_speed = rk3288_gmac_fix_mac_speed, 375 .set_to_rgmii = rk3288_gmac_set_to_rgmii, 376 }; 377 378 const struct rk_gmac_ops rk3368_gmac_ops = { 379 .fix_mac_speed = rk3368_gmac_fix_mac_speed, 380 .set_to_rgmii = rk3368_gmac_set_to_rgmii, 381 }; 382 383 const struct rk_gmac_ops rk3399_gmac_ops = { 384 .fix_mac_speed = rk3399_gmac_fix_mac_speed, 385 .set_to_rgmii = rk3399_gmac_set_to_rgmii, 386 }; 387 388 const struct rk_gmac_ops rv1108_gmac_ops = { 389 .fix_mac_speed = rv1108_set_rmii_speed, 390 .set_to_rmii = rv1108_gmac_set_to_rmii, 391 }; 392 393 static const struct udevice_id rockchip_gmac_ids[] = { 394 { .compatible = "rockchip,rk3288-gmac", 395 .data = (ulong)&rk3288_gmac_ops }, 396 { .compatible = "rockchip,rk3368-gmac", 397 .data = (ulong)&rk3368_gmac_ops }, 398 { .compatible = "rockchip,rk3399-gmac", 399 .data = (ulong)&rk3399_gmac_ops }, 400 { .compatible = "rockchip,rv1108-gmac", 401 .data = (ulong)&rv1108_gmac_ops }, 402 { } 403 }; 404 405 U_BOOT_DRIVER(eth_gmac_rockchip) = { 406 .name = "gmac_rockchip", 407 .id = UCLASS_ETH, 408 .of_match = rockchip_gmac_ids, 409 .ofdata_to_platdata = gmac_rockchip_ofdata_to_platdata, 410 .probe = gmac_rockchip_probe, 411 .ops = &gmac_rockchip_eth_ops, 412 .priv_auto_alloc_size = sizeof(struct dw_eth_dev), 413 .platdata_auto_alloc_size = sizeof(struct gmac_rockchip_platdata), 414 .flags = DM_FLAG_ALLOC_PRIV_DMA, 415 }; 416