dwmac-dwc-qos-eth.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Synopsys DWC Ethernet Quality-of-Service v4.10a linux driver
  4. *
  5. * Copyright (C) 2016 Joao Pinto <[email protected]>
  6. */
  7. #include <linux/clk.h>
  8. #include <linux/clk-provider.h>
  9. #include <linux/device.h>
  10. #include <linux/gpio/consumer.h>
  11. #include <linux/ethtool.h>
  12. #include <linux/io.h>
  13. #include <linux/iopoll.h>
  14. #include <linux/ioport.h>
  15. #include <linux/module.h>
  16. #include <linux/of_device.h>
  17. #include <linux/of_net.h>
  18. #include <linux/mfd/syscon.h>
  19. #include <linux/platform_device.h>
  20. #include <linux/reset.h>
  21. #include <linux/stmmac.h>
  22. #include "stmmac_platform.h"
  23. #include "dwmac4.h"
  24. struct tegra_eqos {
  25. struct device *dev;
  26. void __iomem *regs;
  27. struct reset_control *rst;
  28. struct clk *clk_master;
  29. struct clk *clk_slave;
  30. struct clk *clk_tx;
  31. struct clk *clk_rx;
  32. struct gpio_desc *reset;
  33. };
  34. static int dwc_eth_dwmac_config_dt(struct platform_device *pdev,
  35. struct plat_stmmacenet_data *plat_dat)
  36. {
  37. struct device *dev = &pdev->dev;
  38. u32 burst_map = 0;
  39. u32 bit_index = 0;
  40. u32 a_index = 0;
  41. if (!plat_dat->axi) {
  42. plat_dat->axi = kzalloc(sizeof(struct stmmac_axi), GFP_KERNEL);
  43. if (!plat_dat->axi)
  44. return -ENOMEM;
  45. }
  46. plat_dat->axi->axi_lpi_en = device_property_read_bool(dev,
  47. "snps,en-lpi");
  48. if (device_property_read_u32(dev, "snps,write-requests",
  49. &plat_dat->axi->axi_wr_osr_lmt)) {
  50. /**
  51. * Since the register has a reset value of 1, if property
  52. * is missing, default to 1.
  53. */
  54. plat_dat->axi->axi_wr_osr_lmt = 1;
  55. } else {
  56. /**
  57. * If property exists, to keep the behavior from dwc_eth_qos,
  58. * subtract one after parsing.
  59. */
  60. plat_dat->axi->axi_wr_osr_lmt--;
  61. }
  62. if (device_property_read_u32(dev, "snps,read-requests",
  63. &plat_dat->axi->axi_rd_osr_lmt)) {
  64. /**
  65. * Since the register has a reset value of 1, if property
  66. * is missing, default to 1.
  67. */
  68. plat_dat->axi->axi_rd_osr_lmt = 1;
  69. } else {
  70. /**
  71. * If property exists, to keep the behavior from dwc_eth_qos,
  72. * subtract one after parsing.
  73. */
  74. plat_dat->axi->axi_rd_osr_lmt--;
  75. }
  76. device_property_read_u32(dev, "snps,burst-map", &burst_map);
  77. /* converts burst-map bitmask to burst array */
  78. for (bit_index = 0; bit_index < 7; bit_index++) {
  79. if (burst_map & (1 << bit_index)) {
  80. switch (bit_index) {
  81. case 0:
  82. plat_dat->axi->axi_blen[a_index] = 4; break;
  83. case 1:
  84. plat_dat->axi->axi_blen[a_index] = 8; break;
  85. case 2:
  86. plat_dat->axi->axi_blen[a_index] = 16; break;
  87. case 3:
  88. plat_dat->axi->axi_blen[a_index] = 32; break;
  89. case 4:
  90. plat_dat->axi->axi_blen[a_index] = 64; break;
  91. case 5:
  92. plat_dat->axi->axi_blen[a_index] = 128; break;
  93. case 6:
  94. plat_dat->axi->axi_blen[a_index] = 256; break;
  95. default:
  96. break;
  97. }
  98. a_index++;
  99. }
  100. }
  101. /* dwc-qos needs GMAC4, AAL, TSO and PMT */
  102. plat_dat->has_gmac4 = 1;
  103. plat_dat->dma_cfg->aal = 1;
  104. plat_dat->tso_en = 1;
  105. plat_dat->pmt = 1;
  106. return 0;
  107. }
  108. static int dwc_qos_probe(struct platform_device *pdev,
  109. struct plat_stmmacenet_data *plat_dat,
  110. struct stmmac_resources *stmmac_res)
  111. {
  112. int err;
  113. plat_dat->stmmac_clk = devm_clk_get(&pdev->dev, "apb_pclk");
  114. if (IS_ERR(plat_dat->stmmac_clk)) {
  115. dev_err(&pdev->dev, "apb_pclk clock not found.\n");
  116. return PTR_ERR(plat_dat->stmmac_clk);
  117. }
  118. err = clk_prepare_enable(plat_dat->stmmac_clk);
  119. if (err < 0) {
  120. dev_err(&pdev->dev, "failed to enable apb_pclk clock: %d\n",
  121. err);
  122. return err;
  123. }
  124. plat_dat->pclk = devm_clk_get(&pdev->dev, "phy_ref_clk");
  125. if (IS_ERR(plat_dat->pclk)) {
  126. dev_err(&pdev->dev, "phy_ref_clk clock not found.\n");
  127. err = PTR_ERR(plat_dat->pclk);
  128. goto disable;
  129. }
  130. err = clk_prepare_enable(plat_dat->pclk);
  131. if (err < 0) {
  132. dev_err(&pdev->dev, "failed to enable phy_ref clock: %d\n",
  133. err);
  134. goto disable;
  135. }
  136. return 0;
  137. disable:
  138. clk_disable_unprepare(plat_dat->stmmac_clk);
  139. return err;
  140. }
  141. static int dwc_qos_remove(struct platform_device *pdev)
  142. {
  143. struct net_device *ndev = platform_get_drvdata(pdev);
  144. struct stmmac_priv *priv = netdev_priv(ndev);
  145. clk_disable_unprepare(priv->plat->pclk);
  146. clk_disable_unprepare(priv->plat->stmmac_clk);
  147. return 0;
  148. }
  149. #define SDMEMCOMPPADCTRL 0x8800
  150. #define SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD BIT(31)
  151. #define AUTO_CAL_CONFIG 0x8804
  152. #define AUTO_CAL_CONFIG_START BIT(31)
  153. #define AUTO_CAL_CONFIG_ENABLE BIT(29)
  154. #define AUTO_CAL_STATUS 0x880c
  155. #define AUTO_CAL_STATUS_ACTIVE BIT(31)
  156. static void tegra_eqos_fix_speed(void *priv, unsigned int speed)
  157. {
  158. struct tegra_eqos *eqos = priv;
  159. unsigned long rate = 125000000;
  160. bool needs_calibration = false;
  161. u32 value;
  162. int err;
  163. switch (speed) {
  164. case SPEED_1000:
  165. needs_calibration = true;
  166. rate = 125000000;
  167. break;
  168. case SPEED_100:
  169. needs_calibration = true;
  170. rate = 25000000;
  171. break;
  172. case SPEED_10:
  173. rate = 2500000;
  174. break;
  175. default:
  176. dev_err(eqos->dev, "invalid speed %u\n", speed);
  177. break;
  178. }
  179. if (needs_calibration) {
  180. /* calibrate */
  181. value = readl(eqos->regs + SDMEMCOMPPADCTRL);
  182. value |= SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD;
  183. writel(value, eqos->regs + SDMEMCOMPPADCTRL);
  184. udelay(1);
  185. value = readl(eqos->regs + AUTO_CAL_CONFIG);
  186. value |= AUTO_CAL_CONFIG_START | AUTO_CAL_CONFIG_ENABLE;
  187. writel(value, eqos->regs + AUTO_CAL_CONFIG);
  188. err = readl_poll_timeout_atomic(eqos->regs + AUTO_CAL_STATUS,
  189. value,
  190. value & AUTO_CAL_STATUS_ACTIVE,
  191. 1, 10);
  192. if (err < 0) {
  193. dev_err(eqos->dev, "calibration did not start\n");
  194. goto failed;
  195. }
  196. err = readl_poll_timeout_atomic(eqos->regs + AUTO_CAL_STATUS,
  197. value,
  198. (value & AUTO_CAL_STATUS_ACTIVE) == 0,
  199. 20, 200);
  200. if (err < 0) {
  201. dev_err(eqos->dev, "calibration didn't finish\n");
  202. goto failed;
  203. }
  204. failed:
  205. value = readl(eqos->regs + SDMEMCOMPPADCTRL);
  206. value &= ~SDMEMCOMPPADCTRL_PAD_E_INPUT_OR_E_PWRD;
  207. writel(value, eqos->regs + SDMEMCOMPPADCTRL);
  208. } else {
  209. value = readl(eqos->regs + AUTO_CAL_CONFIG);
  210. value &= ~AUTO_CAL_CONFIG_ENABLE;
  211. writel(value, eqos->regs + AUTO_CAL_CONFIG);
  212. }
  213. err = clk_set_rate(eqos->clk_tx, rate);
  214. if (err < 0)
  215. dev_err(eqos->dev, "failed to set TX rate: %d\n", err);
  216. }
  217. static int tegra_eqos_init(struct platform_device *pdev, void *priv)
  218. {
  219. struct tegra_eqos *eqos = priv;
  220. unsigned long rate;
  221. u32 value;
  222. rate = clk_get_rate(eqos->clk_slave);
  223. value = (rate / 1000000) - 1;
  224. writel(value, eqos->regs + GMAC_1US_TIC_COUNTER);
  225. return 0;
  226. }
  227. static int tegra_eqos_probe(struct platform_device *pdev,
  228. struct plat_stmmacenet_data *data,
  229. struct stmmac_resources *res)
  230. {
  231. struct device *dev = &pdev->dev;
  232. struct tegra_eqos *eqos;
  233. int err;
  234. eqos = devm_kzalloc(&pdev->dev, sizeof(*eqos), GFP_KERNEL);
  235. if (!eqos)
  236. return -ENOMEM;
  237. eqos->dev = &pdev->dev;
  238. eqos->regs = res->addr;
  239. if (!is_of_node(dev->fwnode))
  240. goto bypass_clk_reset_gpio;
  241. eqos->clk_master = devm_clk_get(&pdev->dev, "master_bus");
  242. if (IS_ERR(eqos->clk_master)) {
  243. err = PTR_ERR(eqos->clk_master);
  244. goto error;
  245. }
  246. err = clk_prepare_enable(eqos->clk_master);
  247. if (err < 0)
  248. goto error;
  249. eqos->clk_slave = devm_clk_get(&pdev->dev, "slave_bus");
  250. if (IS_ERR(eqos->clk_slave)) {
  251. err = PTR_ERR(eqos->clk_slave);
  252. goto disable_master;
  253. }
  254. data->stmmac_clk = eqos->clk_slave;
  255. err = clk_prepare_enable(eqos->clk_slave);
  256. if (err < 0)
  257. goto disable_master;
  258. eqos->clk_rx = devm_clk_get(&pdev->dev, "rx");
  259. if (IS_ERR(eqos->clk_rx)) {
  260. err = PTR_ERR(eqos->clk_rx);
  261. goto disable_slave;
  262. }
  263. err = clk_prepare_enable(eqos->clk_rx);
  264. if (err < 0)
  265. goto disable_slave;
  266. eqos->clk_tx = devm_clk_get(&pdev->dev, "tx");
  267. if (IS_ERR(eqos->clk_tx)) {
  268. err = PTR_ERR(eqos->clk_tx);
  269. goto disable_rx;
  270. }
  271. err = clk_prepare_enable(eqos->clk_tx);
  272. if (err < 0)
  273. goto disable_rx;
  274. eqos->reset = devm_gpiod_get(&pdev->dev, "phy-reset", GPIOD_OUT_HIGH);
  275. if (IS_ERR(eqos->reset)) {
  276. err = PTR_ERR(eqos->reset);
  277. goto disable_tx;
  278. }
  279. usleep_range(2000, 4000);
  280. gpiod_set_value(eqos->reset, 0);
  281. /* MDIO bus was already reset just above */
  282. data->mdio_bus_data->needs_reset = false;
  283. eqos->rst = devm_reset_control_get(&pdev->dev, "eqos");
  284. if (IS_ERR(eqos->rst)) {
  285. err = PTR_ERR(eqos->rst);
  286. goto reset_phy;
  287. }
  288. err = reset_control_assert(eqos->rst);
  289. if (err < 0)
  290. goto reset_phy;
  291. usleep_range(2000, 4000);
  292. err = reset_control_deassert(eqos->rst);
  293. if (err < 0)
  294. goto reset_phy;
  295. usleep_range(2000, 4000);
  296. bypass_clk_reset_gpio:
  297. data->fix_mac_speed = tegra_eqos_fix_speed;
  298. data->init = tegra_eqos_init;
  299. data->bsp_priv = eqos;
  300. data->sph_disable = 1;
  301. err = tegra_eqos_init(pdev, eqos);
  302. if (err < 0)
  303. goto reset;
  304. return 0;
  305. reset:
  306. reset_control_assert(eqos->rst);
  307. reset_phy:
  308. gpiod_set_value(eqos->reset, 1);
  309. disable_tx:
  310. clk_disable_unprepare(eqos->clk_tx);
  311. disable_rx:
  312. clk_disable_unprepare(eqos->clk_rx);
  313. disable_slave:
  314. clk_disable_unprepare(eqos->clk_slave);
  315. disable_master:
  316. clk_disable_unprepare(eqos->clk_master);
  317. error:
  318. return err;
  319. }
  320. static int tegra_eqos_remove(struct platform_device *pdev)
  321. {
  322. struct tegra_eqos *eqos = get_stmmac_bsp_priv(&pdev->dev);
  323. reset_control_assert(eqos->rst);
  324. gpiod_set_value(eqos->reset, 1);
  325. clk_disable_unprepare(eqos->clk_tx);
  326. clk_disable_unprepare(eqos->clk_rx);
  327. clk_disable_unprepare(eqos->clk_slave);
  328. clk_disable_unprepare(eqos->clk_master);
  329. return 0;
  330. }
  331. struct dwc_eth_dwmac_data {
  332. int (*probe)(struct platform_device *pdev,
  333. struct plat_stmmacenet_data *data,
  334. struct stmmac_resources *res);
  335. int (*remove)(struct platform_device *pdev);
  336. };
  337. static const struct dwc_eth_dwmac_data dwc_qos_data = {
  338. .probe = dwc_qos_probe,
  339. .remove = dwc_qos_remove,
  340. };
  341. static const struct dwc_eth_dwmac_data tegra_eqos_data = {
  342. .probe = tegra_eqos_probe,
  343. .remove = tegra_eqos_remove,
  344. };
  345. static int dwc_eth_dwmac_probe(struct platform_device *pdev)
  346. {
  347. const struct dwc_eth_dwmac_data *data;
  348. struct plat_stmmacenet_data *plat_dat;
  349. struct stmmac_resources stmmac_res;
  350. int ret;
  351. data = device_get_match_data(&pdev->dev);
  352. memset(&stmmac_res, 0, sizeof(struct stmmac_resources));
  353. /**
  354. * Since stmmac_platform supports name IRQ only, basic platform
  355. * resource initialization is done in the glue logic.
  356. */
  357. stmmac_res.irq = platform_get_irq(pdev, 0);
  358. if (stmmac_res.irq < 0)
  359. return stmmac_res.irq;
  360. stmmac_res.wol_irq = stmmac_res.irq;
  361. stmmac_res.addr = devm_platform_ioremap_resource(pdev, 0);
  362. if (IS_ERR(stmmac_res.addr))
  363. return PTR_ERR(stmmac_res.addr);
  364. plat_dat = stmmac_probe_config_dt(pdev, stmmac_res.mac);
  365. if (IS_ERR(plat_dat))
  366. return PTR_ERR(plat_dat);
  367. ret = data->probe(pdev, plat_dat, &stmmac_res);
  368. if (ret < 0) {
  369. dev_err_probe(&pdev->dev, ret, "failed to probe subdriver\n");
  370. goto remove_config;
  371. }
  372. ret = dwc_eth_dwmac_config_dt(pdev, plat_dat);
  373. if (ret)
  374. goto remove;
  375. ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
  376. if (ret)
  377. goto remove;
  378. return ret;
  379. remove:
  380. data->remove(pdev);
  381. remove_config:
  382. stmmac_remove_config_dt(pdev, plat_dat);
  383. return ret;
  384. }
  385. static int dwc_eth_dwmac_remove(struct platform_device *pdev)
  386. {
  387. struct net_device *ndev = platform_get_drvdata(pdev);
  388. struct stmmac_priv *priv = netdev_priv(ndev);
  389. const struct dwc_eth_dwmac_data *data;
  390. int err;
  391. data = device_get_match_data(&pdev->dev);
  392. err = stmmac_dvr_remove(&pdev->dev);
  393. if (err < 0)
  394. dev_err(&pdev->dev, "failed to remove platform: %d\n", err);
  395. err = data->remove(pdev);
  396. if (err < 0)
  397. dev_err(&pdev->dev, "failed to remove subdriver: %d\n", err);
  398. stmmac_remove_config_dt(pdev, priv->plat);
  399. return err;
  400. }
  401. static const struct of_device_id dwc_eth_dwmac_match[] = {
  402. { .compatible = "snps,dwc-qos-ethernet-4.10", .data = &dwc_qos_data },
  403. { .compatible = "nvidia,tegra186-eqos", .data = &tegra_eqos_data },
  404. { }
  405. };
  406. MODULE_DEVICE_TABLE(of, dwc_eth_dwmac_match);
  407. static struct platform_driver dwc_eth_dwmac_driver = {
  408. .probe = dwc_eth_dwmac_probe,
  409. .remove = dwc_eth_dwmac_remove,
  410. .driver = {
  411. .name = "dwc-eth-dwmac",
  412. .pm = &stmmac_pltfr_pm_ops,
  413. .of_match_table = dwc_eth_dwmac_match,
  414. },
  415. };
  416. module_platform_driver(dwc_eth_dwmac_driver);
  417. MODULE_AUTHOR("Joao Pinto <[email protected]>");
  418. MODULE_DESCRIPTION("Synopsys DWC Ethernet Quality-of-Service v4.10a driver");
  419. MODULE_LICENSE("GPL v2");