cpsw_mdio.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * CPSW MDIO generic driver for TI AMxx/K2x/EMAC devices.
  4. *
  5. * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
  6. */
  7. #include <common.h>
  8. #include <asm/io.h>
  9. #include <miiphy.h>
  10. #include <wait_bit.h>
  11. struct cpsw_mdio_regs {
  12. u32 version;
  13. u32 control;
  14. #define CONTROL_IDLE BIT(31)
  15. #define CONTROL_ENABLE BIT(30)
  16. #define CONTROL_FAULT BIT(19)
  17. #define CONTROL_FAULT_ENABLE BIT(18)
  18. #define CONTROL_DIV_MASK GENMASK(15, 0)
  19. u32 alive;
  20. u32 link;
  21. u32 linkintraw;
  22. u32 linkintmasked;
  23. u32 __reserved_0[2];
  24. u32 userintraw;
  25. u32 userintmasked;
  26. u32 userintmaskset;
  27. u32 userintmaskclr;
  28. u32 __reserved_1[20];
  29. struct {
  30. u32 access;
  31. u32 physel;
  32. #define USERACCESS_GO BIT(31)
  33. #define USERACCESS_WRITE BIT(30)
  34. #define USERACCESS_ACK BIT(29)
  35. #define USERACCESS_READ (0)
  36. #define USERACCESS_PHY_REG_SHIFT (21)
  37. #define USERACCESS_PHY_ADDR_SHIFT (16)
  38. #define USERACCESS_DATA GENMASK(15, 0)
  39. } user[0];
  40. };
  41. #define CPSW_MDIO_DIV_DEF 0xff
  42. #define PHY_REG_MASK 0x1f
  43. #define PHY_ID_MASK 0x1f
  44. /*
  45. * This timeout definition is a worst-case ultra defensive measure against
  46. * unexpected controller lock ups. Ideally, we should never ever hit this
  47. * scenario in practice.
  48. */
  49. #define CPSW_MDIO_TIMEOUT 100 /* msecs */
  50. struct cpsw_mdio {
  51. struct cpsw_mdio_regs *regs;
  52. struct mii_dev *bus;
  53. int div;
  54. };
  55. /* wait until hardware is ready for another user access */
  56. static int cpsw_mdio_wait_for_user_access(struct cpsw_mdio *mdio)
  57. {
  58. return wait_for_bit_le32(&mdio->regs->user[0].access,
  59. USERACCESS_GO, false,
  60. CPSW_MDIO_TIMEOUT, false);
  61. }
  62. static int cpsw_mdio_read(struct mii_dev *bus, int phy_id,
  63. int dev_addr, int phy_reg)
  64. {
  65. struct cpsw_mdio *mdio = bus->priv;
  66. int data, ret;
  67. u32 reg;
  68. if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
  69. return -EINVAL;
  70. ret = cpsw_mdio_wait_for_user_access(mdio);
  71. if (ret)
  72. return ret;
  73. reg = (USERACCESS_GO | USERACCESS_READ |
  74. (phy_reg << USERACCESS_PHY_REG_SHIFT) |
  75. (phy_id << USERACCESS_PHY_ADDR_SHIFT));
  76. writel(reg, &mdio->regs->user[0].access);
  77. ret = cpsw_mdio_wait_for_user_access(mdio);
  78. if (ret)
  79. return ret;
  80. reg = readl(&mdio->regs->user[0].access);
  81. data = (reg & USERACCESS_ACK) ? (reg & USERACCESS_DATA) : -1;
  82. return data;
  83. }
  84. static int cpsw_mdio_write(struct mii_dev *bus, int phy_id, int dev_addr,
  85. int phy_reg, u16 data)
  86. {
  87. struct cpsw_mdio *mdio = bus->priv;
  88. u32 reg;
  89. int ret;
  90. if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
  91. return -EINVAL;
  92. ret = cpsw_mdio_wait_for_user_access(mdio);
  93. if (ret)
  94. return ret;
  95. reg = (USERACCESS_GO | USERACCESS_WRITE |
  96. (phy_reg << USERACCESS_PHY_REG_SHIFT) |
  97. (phy_id << USERACCESS_PHY_ADDR_SHIFT) |
  98. (data & USERACCESS_DATA));
  99. writel(reg, &mdio->regs->user[0].access);
  100. return cpsw_mdio_wait_for_user_access(mdio);
  101. }
  102. u32 cpsw_mdio_get_alive(struct mii_dev *bus)
  103. {
  104. struct cpsw_mdio *mdio = bus->priv;
  105. u32 val;
  106. val = readl(&mdio->regs->control);
  107. return val & GENMASK(15, 0);
  108. }
  109. struct mii_dev *cpsw_mdio_init(const char *name, phys_addr_t mdio_base,
  110. u32 bus_freq, int fck_freq)
  111. {
  112. struct cpsw_mdio *cpsw_mdio;
  113. int ret;
  114. cpsw_mdio = calloc(1, sizeof(*cpsw_mdio));
  115. if (!cpsw_mdio) {
  116. debug("failed to alloc cpsw_mdio\n");
  117. return NULL;
  118. }
  119. cpsw_mdio->bus = mdio_alloc();
  120. if (!cpsw_mdio->bus) {
  121. debug("failed to alloc mii bus\n");
  122. free(cpsw_mdio);
  123. return NULL;
  124. }
  125. cpsw_mdio->regs = (struct cpsw_mdio_regs *)(uintptr_t)mdio_base;
  126. if (!bus_freq || !fck_freq)
  127. cpsw_mdio->div = CPSW_MDIO_DIV_DEF;
  128. else
  129. cpsw_mdio->div = (fck_freq / bus_freq) - 1;
  130. cpsw_mdio->div &= CONTROL_DIV_MASK;
  131. /* set enable and clock divider */
  132. writel(cpsw_mdio->div | CONTROL_ENABLE | CONTROL_FAULT |
  133. CONTROL_FAULT_ENABLE, &cpsw_mdio->regs->control);
  134. wait_for_bit_le32(&cpsw_mdio->regs->control,
  135. CONTROL_IDLE, false, CPSW_MDIO_TIMEOUT, true);
  136. /*
  137. * wait for scan logic to settle:
  138. * the scan time consists of (a) a large fixed component, and (b) a
  139. * small component that varies with the mii bus frequency. These
  140. * were estimated using measurements at 1.1 and 2.2 MHz on tnetv107x
  141. * silicon. Since the effect of (b) was found to be largely
  142. * negligible, we keep things simple here.
  143. */
  144. mdelay(1);
  145. cpsw_mdio->bus->read = cpsw_mdio_read;
  146. cpsw_mdio->bus->write = cpsw_mdio_write;
  147. cpsw_mdio->bus->priv = cpsw_mdio;
  148. snprintf(cpsw_mdio->bus->name, sizeof(cpsw_mdio->bus->name), name);
  149. ret = mdio_register(cpsw_mdio->bus);
  150. if (ret < 0) {
  151. debug("failed to register mii bus\n");
  152. goto free_bus;
  153. }
  154. return cpsw_mdio->bus;
  155. free_bus:
  156. mdio_free(cpsw_mdio->bus);
  157. free(cpsw_mdio);
  158. return NULL;
  159. }
  160. void cpsw_mdio_free(struct mii_dev *bus)
  161. {
  162. struct cpsw_mdio *mdio = bus->priv;
  163. u32 reg;
  164. /* disable mdio */
  165. reg = readl(&mdio->regs->control);
  166. reg &= ~CONTROL_ENABLE;
  167. writel(reg, &mdio->regs->control);
  168. mdio_unregister(bus);
  169. mdio_free(bus);
  170. free(mdio);
  171. }