higmacv300.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2019, Linaro Limited
  4. */
  5. #include <asm/io.h>
  6. #include <common.h>
  7. #include <console.h>
  8. #include <linux/bug.h>
  9. #include <linux/mii.h>
  10. #include <miiphy.h>
  11. #include <net.h>
  12. #include <reset.h>
  13. #include <wait_bit.h>
  14. #define STATION_ADDR_LOW 0x0000
  15. #define STATION_ADDR_HIGH 0x0004
  16. #define MAC_DUPLEX_HALF_CTRL 0x0008
  17. #define PORT_MODE 0x0040
  18. #define PORT_EN 0x0044
  19. #define BIT_TX_EN BIT(2)
  20. #define BIT_RX_EN BIT(1)
  21. #define MODE_CHANGE_EN 0x01b4
  22. #define BIT_MODE_CHANGE_EN BIT(0)
  23. #define MDIO_SINGLE_CMD 0x03c0
  24. #define BIT_MDIO_BUSY BIT(20)
  25. #define MDIO_READ (BIT(17) | BIT_MDIO_BUSY)
  26. #define MDIO_WRITE (BIT(16) | BIT_MDIO_BUSY)
  27. #define MDIO_SINGLE_DATA 0x03c4
  28. #define MDIO_RDATA_STATUS 0x03d0
  29. #define BIT_MDIO_RDATA_INVALID BIT(0)
  30. #define RX_FQ_START_ADDR 0x0500
  31. #define RX_FQ_DEPTH 0x0504
  32. #define RX_FQ_WR_ADDR 0x0508
  33. #define RX_FQ_RD_ADDR 0x050c
  34. #define RX_FQ_REG_EN 0x0518
  35. #define RX_BQ_START_ADDR 0x0520
  36. #define RX_BQ_DEPTH 0x0524
  37. #define RX_BQ_WR_ADDR 0x0528
  38. #define RX_BQ_RD_ADDR 0x052c
  39. #define RX_BQ_REG_EN 0x0538
  40. #define TX_BQ_START_ADDR 0x0580
  41. #define TX_BQ_DEPTH 0x0584
  42. #define TX_BQ_WR_ADDR 0x0588
  43. #define TX_BQ_RD_ADDR 0x058c
  44. #define TX_BQ_REG_EN 0x0598
  45. #define TX_RQ_START_ADDR 0x05a0
  46. #define TX_RQ_DEPTH 0x05a4
  47. #define TX_RQ_WR_ADDR 0x05a8
  48. #define TX_RQ_RD_ADDR 0x05ac
  49. #define TX_RQ_REG_EN 0x05b8
  50. #define BIT_START_ADDR_EN BIT(2)
  51. #define BIT_DEPTH_EN BIT(1)
  52. #define DESC_WR_RD_ENA 0x05cc
  53. #define BIT_RX_OUTCFF_WR BIT(3)
  54. #define BIT_RX_CFF_RD BIT(2)
  55. #define BIT_TX_OUTCFF_WR BIT(1)
  56. #define BIT_TX_CFF_RD BIT(0)
  57. #define BITS_DESC_ENA (BIT_RX_OUTCFF_WR | BIT_RX_CFF_RD | \
  58. BIT_TX_OUTCFF_WR | BIT_TX_CFF_RD)
  59. /* MACIF_CTRL */
  60. #define RGMII_SPEED_1000 0x2c
  61. #define RGMII_SPEED_100 0x2f
  62. #define RGMII_SPEED_10 0x2d
  63. #define MII_SPEED_100 0x0f
  64. #define MII_SPEED_10 0x0d
  65. #define GMAC_SPEED_1000 0x05
  66. #define GMAC_SPEED_100 0x01
  67. #define GMAC_SPEED_10 0x00
  68. #define GMAC_FULL_DUPLEX BIT(4)
  69. #define RX_DESC_NUM 64
  70. #define TX_DESC_NUM 2
  71. #define DESC_SIZE 32
  72. #define DESC_WORD_SHIFT 3
  73. #define DESC_BYTE_SHIFT 5
  74. #define DESC_CNT(n) ((n) >> DESC_BYTE_SHIFT)
  75. #define DESC_BYTE(n) ((n) << DESC_BYTE_SHIFT)
  76. #define DESC_VLD_FREE 0
  77. #define DESC_VLD_BUSY 1
  78. #define MAC_MAX_FRAME_SIZE 1600
  79. enum higmac_queue {
  80. RX_FQ,
  81. RX_BQ,
  82. TX_BQ,
  83. TX_RQ,
  84. };
  85. struct higmac_desc {
  86. unsigned int buf_addr;
  87. unsigned int buf_len:11;
  88. unsigned int reserve0:5;
  89. unsigned int data_len:11;
  90. unsigned int reserve1:2;
  91. unsigned int fl:2;
  92. unsigned int descvid:1;
  93. unsigned int reserve2[6];
  94. };
  95. struct higmac_priv {
  96. void __iomem *base;
  97. void __iomem *macif_ctrl;
  98. struct reset_ctl rst_phy;
  99. struct higmac_desc *rxfq;
  100. struct higmac_desc *rxbq;
  101. struct higmac_desc *txbq;
  102. struct higmac_desc *txrq;
  103. int rxdesc_in_use;
  104. struct mii_dev *bus;
  105. struct phy_device *phydev;
  106. int phyintf;
  107. int phyaddr;
  108. };
  109. #define flush_desc(d) flush_cache((unsigned long)(d), sizeof(*(d)))
  110. #define invalidate_desc(d) \
  111. invalidate_dcache_range((unsigned long)(d), \
  112. (unsigned long)(d) + sizeof(*(d)))
  113. static int higmac_write_hwaddr(struct udevice *dev)
  114. {
  115. struct eth_pdata *pdata = dev_get_platdata(dev);
  116. struct higmac_priv *priv = dev_get_priv(dev);
  117. unsigned char *mac = pdata->enetaddr;
  118. u32 val;
  119. val = mac[1] | (mac[0] << 8);
  120. writel(val, priv->base + STATION_ADDR_HIGH);
  121. val = mac[5] | (mac[4] << 8) | (mac[3] << 16) | (mac[2] << 24);
  122. writel(val, priv->base + STATION_ADDR_LOW);
  123. return 0;
  124. }
  125. static int higmac_free_pkt(struct udevice *dev, uchar *packet, int length)
  126. {
  127. struct higmac_priv *priv = dev_get_priv(dev);
  128. /* Inform GMAC that the RX descriptor is no longer in use */
  129. writel(DESC_BYTE(priv->rxdesc_in_use), priv->base + RX_BQ_RD_ADDR);
  130. return 0;
  131. }
  132. static int higmac_recv(struct udevice *dev, int flags, uchar **packetp)
  133. {
  134. struct higmac_priv *priv = dev_get_priv(dev);
  135. struct higmac_desc *fqd = priv->rxfq;
  136. struct higmac_desc *bqd = priv->rxbq;
  137. int fqw_pos, fqr_pos, bqw_pos, bqr_pos;
  138. int timeout = 100000;
  139. int len = 0;
  140. int space;
  141. int i;
  142. fqw_pos = DESC_CNT(readl(priv->base + RX_FQ_WR_ADDR));
  143. fqr_pos = DESC_CNT(readl(priv->base + RX_FQ_RD_ADDR));
  144. if (fqw_pos >= fqr_pos)
  145. space = RX_DESC_NUM - (fqw_pos - fqr_pos);
  146. else
  147. space = fqr_pos - fqw_pos;
  148. /* Leave one free to distinguish full filled from empty buffer */
  149. for (i = 0; i < space - 1; i++) {
  150. fqd = priv->rxfq + fqw_pos;
  151. invalidate_dcache_range(fqd->buf_addr,
  152. fqd->buf_addr + MAC_MAX_FRAME_SIZE);
  153. if (++fqw_pos >= RX_DESC_NUM)
  154. fqw_pos = 0;
  155. writel(DESC_BYTE(fqw_pos), priv->base + RX_FQ_WR_ADDR);
  156. }
  157. bqr_pos = DESC_CNT(readl(priv->base + RX_BQ_RD_ADDR));
  158. bqd += bqr_pos;
  159. /* BQ is only ever written by GMAC */
  160. invalidate_desc(bqd);
  161. do {
  162. bqw_pos = DESC_CNT(readl(priv->base + RX_BQ_WR_ADDR));
  163. udelay(1);
  164. } while (--timeout && bqw_pos == bqr_pos);
  165. if (!timeout)
  166. return -ETIMEDOUT;
  167. if (++bqr_pos >= RX_DESC_NUM)
  168. bqr_pos = 0;
  169. len = bqd->data_len;
  170. /* CPU should not have touched this buffer since we added it to FQ */
  171. invalidate_dcache_range(bqd->buf_addr, bqd->buf_addr + len);
  172. *packetp = (void *)(unsigned long)bqd->buf_addr;
  173. /* Record the RX_BQ descriptor that is holding RX data */
  174. priv->rxdesc_in_use = bqr_pos;
  175. return len;
  176. }
  177. static int higmac_send(struct udevice *dev, void *packet, int length)
  178. {
  179. struct higmac_priv *priv = dev_get_priv(dev);
  180. struct higmac_desc *bqd = priv->txbq;
  181. int bqw_pos, rqw_pos, rqr_pos;
  182. int timeout = 1000;
  183. flush_cache((unsigned long)packet, length);
  184. bqw_pos = DESC_CNT(readl(priv->base + TX_BQ_WR_ADDR));
  185. bqd += bqw_pos;
  186. bqd->buf_addr = (unsigned long)packet;
  187. bqd->descvid = DESC_VLD_BUSY;
  188. bqd->data_len = length;
  189. flush_desc(bqd);
  190. if (++bqw_pos >= TX_DESC_NUM)
  191. bqw_pos = 0;
  192. writel(DESC_BYTE(bqw_pos), priv->base + TX_BQ_WR_ADDR);
  193. rqr_pos = DESC_CNT(readl(priv->base + TX_RQ_RD_ADDR));
  194. if (++rqr_pos >= TX_DESC_NUM)
  195. rqr_pos = 0;
  196. do {
  197. rqw_pos = DESC_CNT(readl(priv->base + TX_RQ_WR_ADDR));
  198. udelay(1);
  199. } while (--timeout && rqr_pos != rqw_pos);
  200. if (!timeout)
  201. return -ETIMEDOUT;
  202. writel(DESC_BYTE(rqr_pos), priv->base + TX_RQ_RD_ADDR);
  203. return 0;
  204. }
  205. static int higmac_adjust_link(struct higmac_priv *priv)
  206. {
  207. struct phy_device *phydev = priv->phydev;
  208. int interface = priv->phyintf;
  209. u32 val;
  210. switch (interface) {
  211. case PHY_INTERFACE_MODE_RGMII:
  212. if (phydev->speed == SPEED_1000)
  213. val = RGMII_SPEED_1000;
  214. else if (phydev->speed == SPEED_100)
  215. val = RGMII_SPEED_100;
  216. else
  217. val = RGMII_SPEED_10;
  218. break;
  219. case PHY_INTERFACE_MODE_MII:
  220. if (phydev->speed == SPEED_100)
  221. val = MII_SPEED_100;
  222. else
  223. val = MII_SPEED_10;
  224. break;
  225. default:
  226. debug("unsupported mode: %d\n", interface);
  227. return -EINVAL;
  228. }
  229. if (phydev->duplex)
  230. val |= GMAC_FULL_DUPLEX;
  231. writel(val, priv->macif_ctrl);
  232. if (phydev->speed == SPEED_1000)
  233. val = GMAC_SPEED_1000;
  234. else if (phydev->speed == SPEED_100)
  235. val = GMAC_SPEED_100;
  236. else
  237. val = GMAC_SPEED_10;
  238. writel(BIT_MODE_CHANGE_EN, priv->base + MODE_CHANGE_EN);
  239. writel(val, priv->base + PORT_MODE);
  240. writel(0, priv->base + MODE_CHANGE_EN);
  241. writel(phydev->duplex, priv->base + MAC_DUPLEX_HALF_CTRL);
  242. return 0;
  243. }
  244. static int higmac_start(struct udevice *dev)
  245. {
  246. struct higmac_priv *priv = dev_get_priv(dev);
  247. struct phy_device *phydev = priv->phydev;
  248. int ret;
  249. ret = phy_startup(phydev);
  250. if (ret)
  251. return ret;
  252. if (!phydev->link) {
  253. debug("%s: link down\n", phydev->dev->name);
  254. return -ENODEV;
  255. }
  256. ret = higmac_adjust_link(priv);
  257. if (ret)
  258. return ret;
  259. /* Enable port */
  260. writel(BITS_DESC_ENA, priv->base + DESC_WR_RD_ENA);
  261. writel(BIT_TX_EN | BIT_RX_EN, priv->base + PORT_EN);
  262. return 0;
  263. }
  264. static void higmac_stop(struct udevice *dev)
  265. {
  266. struct higmac_priv *priv = dev_get_priv(dev);
  267. /* Disable port */
  268. writel(0, priv->base + PORT_EN);
  269. writel(0, priv->base + DESC_WR_RD_ENA);
  270. }
  271. static const struct eth_ops higmac_ops = {
  272. .start = higmac_start,
  273. .send = higmac_send,
  274. .recv = higmac_recv,
  275. .free_pkt = higmac_free_pkt,
  276. .stop = higmac_stop,
  277. .write_hwaddr = higmac_write_hwaddr,
  278. };
  279. static int higmac_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
  280. {
  281. struct higmac_priv *priv = bus->priv;
  282. int ret;
  283. ret = wait_for_bit_le32(priv->base + MDIO_SINGLE_CMD, BIT_MDIO_BUSY,
  284. false, 1000, false);
  285. if (ret)
  286. return ret;
  287. writel(MDIO_READ | addr << 8 | reg, priv->base + MDIO_SINGLE_CMD);
  288. ret = wait_for_bit_le32(priv->base + MDIO_SINGLE_CMD, BIT_MDIO_BUSY,
  289. false, 1000, false);
  290. if (ret)
  291. return ret;
  292. if (readl(priv->base + MDIO_RDATA_STATUS) & BIT_MDIO_RDATA_INVALID)
  293. return -EINVAL;
  294. return readl(priv->base + MDIO_SINGLE_DATA) >> 16;
  295. }
  296. static int higmac_mdio_write(struct mii_dev *bus, int addr, int devad,
  297. int reg, u16 value)
  298. {
  299. struct higmac_priv *priv = bus->priv;
  300. int ret;
  301. ret = wait_for_bit_le32(priv->base + MDIO_SINGLE_CMD, BIT_MDIO_BUSY,
  302. false, 1000, false);
  303. if (ret)
  304. return ret;
  305. writel(value, priv->base + MDIO_SINGLE_DATA);
  306. writel(MDIO_WRITE | addr << 8 | reg, priv->base + MDIO_SINGLE_CMD);
  307. return 0;
  308. }
  309. static int higmac_init_rx_descs(struct higmac_desc *descs, int num)
  310. {
  311. int i;
  312. for (i = 0; i < num; i++) {
  313. struct higmac_desc *desc = &descs[i];
  314. desc->buf_addr = (unsigned long)memalign(ARCH_DMA_MINALIGN,
  315. MAC_MAX_FRAME_SIZE);
  316. if (!desc->buf_addr)
  317. goto free_bufs;
  318. desc->descvid = DESC_VLD_FREE;
  319. desc->buf_len = MAC_MAX_FRAME_SIZE - 1;
  320. flush_desc(desc);
  321. }
  322. return 0;
  323. free_bufs:
  324. while (--i > 0)
  325. free((void *)(unsigned long)descs[i].buf_addr);
  326. return -ENOMEM;
  327. }
  328. static int higmac_init_hw_queue(struct higmac_priv *priv,
  329. enum higmac_queue queue)
  330. {
  331. struct higmac_desc *desc, **pdesc;
  332. u32 regaddr, regen, regdep;
  333. int depth;
  334. int len;
  335. switch (queue) {
  336. case RX_FQ:
  337. regaddr = RX_FQ_START_ADDR;
  338. regen = RX_FQ_REG_EN;
  339. regdep = RX_FQ_DEPTH;
  340. depth = RX_DESC_NUM;
  341. pdesc = &priv->rxfq;
  342. break;
  343. case RX_BQ:
  344. regaddr = RX_BQ_START_ADDR;
  345. regen = RX_BQ_REG_EN;
  346. regdep = RX_BQ_DEPTH;
  347. depth = RX_DESC_NUM;
  348. pdesc = &priv->rxbq;
  349. break;
  350. case TX_BQ:
  351. regaddr = TX_BQ_START_ADDR;
  352. regen = TX_BQ_REG_EN;
  353. regdep = TX_BQ_DEPTH;
  354. depth = TX_DESC_NUM;
  355. pdesc = &priv->txbq;
  356. break;
  357. case TX_RQ:
  358. regaddr = TX_RQ_START_ADDR;
  359. regen = TX_RQ_REG_EN;
  360. regdep = TX_RQ_DEPTH;
  361. depth = TX_DESC_NUM;
  362. pdesc = &priv->txrq;
  363. break;
  364. }
  365. /* Enable depth */
  366. writel(BIT_DEPTH_EN, priv->base + regen);
  367. writel(depth << DESC_WORD_SHIFT, priv->base + regdep);
  368. writel(0, priv->base + regen);
  369. len = depth * sizeof(*desc);
  370. desc = memalign(ARCH_DMA_MINALIGN, len);
  371. if (!desc)
  372. return -ENOMEM;
  373. memset(desc, 0, len);
  374. flush_cache((unsigned long)desc, len);
  375. *pdesc = desc;
  376. /* Set up RX_FQ descriptors */
  377. if (queue == RX_FQ)
  378. higmac_init_rx_descs(desc, depth);
  379. /* Enable start address */
  380. writel(BIT_START_ADDR_EN, priv->base + regen);
  381. writel((unsigned long)desc, priv->base + regaddr);
  382. writel(0, priv->base + regen);
  383. return 0;
  384. }
  385. static int higmac_hw_init(struct higmac_priv *priv)
  386. {
  387. int ret;
  388. /* Initialize hardware queues */
  389. ret = higmac_init_hw_queue(priv, RX_FQ);
  390. if (ret)
  391. return ret;
  392. ret = higmac_init_hw_queue(priv, RX_BQ);
  393. if (ret)
  394. goto free_rx_fq;
  395. ret = higmac_init_hw_queue(priv, TX_BQ);
  396. if (ret)
  397. goto free_rx_bq;
  398. ret = higmac_init_hw_queue(priv, TX_RQ);
  399. if (ret)
  400. goto free_tx_bq;
  401. /* Reset phy */
  402. reset_deassert(&priv->rst_phy);
  403. mdelay(10);
  404. reset_assert(&priv->rst_phy);
  405. mdelay(30);
  406. reset_deassert(&priv->rst_phy);
  407. mdelay(30);
  408. return 0;
  409. free_tx_bq:
  410. free(priv->txbq);
  411. free_rx_bq:
  412. free(priv->rxbq);
  413. free_rx_fq:
  414. free(priv->rxfq);
  415. return ret;
  416. }
  417. static int higmac_probe(struct udevice *dev)
  418. {
  419. struct higmac_priv *priv = dev_get_priv(dev);
  420. struct phy_device *phydev;
  421. struct mii_dev *bus;
  422. int ret;
  423. ret = higmac_hw_init(priv);
  424. if (ret)
  425. return ret;
  426. bus = mdio_alloc();
  427. if (!bus)
  428. return -ENOMEM;
  429. bus->read = higmac_mdio_read;
  430. bus->write = higmac_mdio_write;
  431. bus->priv = priv;
  432. priv->bus = bus;
  433. ret = mdio_register_seq(bus, dev->seq);
  434. if (ret)
  435. return ret;
  436. phydev = phy_connect(bus, priv->phyaddr, dev, priv->phyintf);
  437. if (!phydev)
  438. return -ENODEV;
  439. phydev->supported &= PHY_GBIT_FEATURES;
  440. phydev->advertising = phydev->supported;
  441. priv->phydev = phydev;
  442. return phy_config(phydev);
  443. }
  444. static int higmac_remove(struct udevice *dev)
  445. {
  446. struct higmac_priv *priv = dev_get_priv(dev);
  447. int i;
  448. mdio_unregister(priv->bus);
  449. mdio_free(priv->bus);
  450. /* Free RX packet buffers */
  451. for (i = 0; i < RX_DESC_NUM; i++)
  452. free((void *)(unsigned long)priv->rxfq[i].buf_addr);
  453. return 0;
  454. }
  455. static int higmac_ofdata_to_platdata(struct udevice *dev)
  456. {
  457. struct higmac_priv *priv = dev_get_priv(dev);
  458. int phyintf = PHY_INTERFACE_MODE_NONE;
  459. const char *phy_mode;
  460. ofnode phy_node;
  461. priv->base = dev_remap_addr_index(dev, 0);
  462. priv->macif_ctrl = dev_remap_addr_index(dev, 1);
  463. phy_mode = dev_read_string(dev, "phy-mode");
  464. if (phy_mode)
  465. phyintf = phy_get_interface_by_name(phy_mode);
  466. if (phyintf == PHY_INTERFACE_MODE_NONE)
  467. return -ENODEV;
  468. priv->phyintf = phyintf;
  469. phy_node = dev_read_subnode(dev, "phy");
  470. if (!ofnode_valid(phy_node)) {
  471. debug("failed to find phy node\n");
  472. return -ENODEV;
  473. }
  474. priv->phyaddr = ofnode_read_u32_default(phy_node, "reg", 0);
  475. return reset_get_by_name(dev, "phy", &priv->rst_phy);
  476. }
  477. static const struct udevice_id higmac_ids[] = {
  478. { .compatible = "hisilicon,hi3798cv200-gmac" },
  479. { }
  480. };
  481. U_BOOT_DRIVER(eth_higmac) = {
  482. .name = "eth_higmac",
  483. .id = UCLASS_ETH,
  484. .of_match = higmac_ids,
  485. .ofdata_to_platdata = higmac_ofdata_to_platdata,
  486. .probe = higmac_probe,
  487. .remove = higmac_remove,
  488. .ops = &higmac_ops,
  489. .priv_auto_alloc_size = sizeof(struct higmac_priv),
  490. .platdata_auto_alloc_size = sizeof(struct eth_pdata),
  491. };