gmac_rockchip.c 13 KB

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