micrel.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /*
  2. * Micrel PHY drivers
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. *
  6. * Copyright 2010-2011 Freescale Semiconductor, Inc.
  7. * author Andy Fleming
  8. * (C) 2012 NetModule AG, David Andrey, added KSZ9031
  9. */
  10. #include <config.h>
  11. #include <common.h>
  12. #include <micrel.h>
  13. #include <phy.h>
  14. static struct phy_driver KSZ804_driver = {
  15. .name = "Micrel KSZ804",
  16. .uid = 0x221510,
  17. .mask = 0xfffff0,
  18. .features = PHY_BASIC_FEATURES,
  19. .config = &genphy_config,
  20. .startup = &genphy_startup,
  21. .shutdown = &genphy_shutdown,
  22. };
  23. #ifndef CONFIG_PHY_MICREL_KSZ9021
  24. /*
  25. * I can't believe Micrel used the exact same part number
  26. * for the KSZ9021. Shame Micrel, Shame!
  27. */
  28. static struct phy_driver KS8721_driver = {
  29. .name = "Micrel KS8721BL",
  30. .uid = 0x221610,
  31. .mask = 0xfffff0,
  32. .features = PHY_BASIC_FEATURES,
  33. .config = &genphy_config,
  34. .startup = &genphy_startup,
  35. .shutdown = &genphy_shutdown,
  36. };
  37. #endif
  38. /*
  39. * KSZ9021 - KSZ9031 common
  40. */
  41. #define MII_KSZ90xx_PHY_CTL 0x1f
  42. #define MIIM_KSZ90xx_PHYCTL_1000 (1 << 6)
  43. #define MIIM_KSZ90xx_PHYCTL_100 (1 << 5)
  44. #define MIIM_KSZ90xx_PHYCTL_10 (1 << 4)
  45. #define MIIM_KSZ90xx_PHYCTL_DUPLEX (1 << 3)
  46. static int ksz90xx_startup(struct phy_device *phydev)
  47. {
  48. unsigned phy_ctl;
  49. genphy_update_link(phydev);
  50. phy_ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ90xx_PHY_CTL);
  51. if (phy_ctl & MIIM_KSZ90xx_PHYCTL_DUPLEX)
  52. phydev->duplex = DUPLEX_FULL;
  53. else
  54. phydev->duplex = DUPLEX_HALF;
  55. if (phy_ctl & MIIM_KSZ90xx_PHYCTL_1000)
  56. phydev->speed = SPEED_1000;
  57. else if (phy_ctl & MIIM_KSZ90xx_PHYCTL_100)
  58. phydev->speed = SPEED_100;
  59. else if (phy_ctl & MIIM_KSZ90xx_PHYCTL_10)
  60. phydev->speed = SPEED_10;
  61. return 0;
  62. }
  63. #ifdef CONFIG_PHY_MICREL_KSZ9021
  64. /*
  65. * KSZ9021
  66. */
  67. /* PHY Registers */
  68. #define MII_KSZ9021_EXTENDED_CTRL 0x0b
  69. #define MII_KSZ9021_EXTENDED_DATAW 0x0c
  70. #define MII_KSZ9021_EXTENDED_DATAR 0x0d
  71. #define CTRL1000_PREFER_MASTER (1 << 10)
  72. #define CTRL1000_CONFIG_MASTER (1 << 11)
  73. #define CTRL1000_MANUAL_CONFIG (1 << 12)
  74. int ksz9021_phy_extended_write(struct phy_device *phydev, int regnum, u16 val)
  75. {
  76. /* extended registers */
  77. phy_write(phydev, MDIO_DEVAD_NONE,
  78. MII_KSZ9021_EXTENDED_CTRL, regnum | 0x8000);
  79. return phy_write(phydev, MDIO_DEVAD_NONE,
  80. MII_KSZ9021_EXTENDED_DATAW, val);
  81. }
  82. int ksz9021_phy_extended_read(struct phy_device *phydev, int regnum)
  83. {
  84. /* extended registers */
  85. phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_CTRL, regnum);
  86. return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_DATAR);
  87. }
  88. static int ksz9021_phy_extread(struct phy_device *phydev, int addr, int devaddr,
  89. int regnum)
  90. {
  91. return ksz9021_phy_extended_read(phydev, regnum);
  92. }
  93. static int ksz9021_phy_extwrite(struct phy_device *phydev, int addr,
  94. int devaddr, int regnum, u16 val)
  95. {
  96. return ksz9021_phy_extended_write(phydev, regnum, val);
  97. }
  98. /* Micrel ksz9021 */
  99. static int ksz9021_config(struct phy_device *phydev)
  100. {
  101. unsigned ctrl1000 = 0;
  102. const unsigned master = CTRL1000_PREFER_MASTER |
  103. CTRL1000_CONFIG_MASTER | CTRL1000_MANUAL_CONFIG;
  104. unsigned features = phydev->drv->features;
  105. if (getenv("disable_giga"))
  106. features &= ~(SUPPORTED_1000baseT_Half |
  107. SUPPORTED_1000baseT_Full);
  108. /* force master mode for 1000BaseT due to chip errata */
  109. if (features & SUPPORTED_1000baseT_Half)
  110. ctrl1000 |= ADVERTISE_1000HALF | master;
  111. if (features & SUPPORTED_1000baseT_Full)
  112. ctrl1000 |= ADVERTISE_1000FULL | master;
  113. phydev->advertising = phydev->supported = features;
  114. phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, ctrl1000);
  115. genphy_config_aneg(phydev);
  116. genphy_restart_aneg(phydev);
  117. return 0;
  118. }
  119. static struct phy_driver ksz9021_driver = {
  120. .name = "Micrel ksz9021",
  121. .uid = 0x221610,
  122. .mask = 0xfffff0,
  123. .features = PHY_GBIT_FEATURES,
  124. .config = &ksz9021_config,
  125. .startup = &ksz90xx_startup,
  126. .shutdown = &genphy_shutdown,
  127. .writeext = &ksz9021_phy_extwrite,
  128. .readext = &ksz9021_phy_extread,
  129. };
  130. #endif
  131. /**
  132. * KSZ9031
  133. */
  134. /* PHY Registers */
  135. #define MII_KSZ9031_MMD_ACCES_CTRL 0x0d
  136. #define MII_KSZ9031_MMD_REG_DATA 0x0e
  137. /* Accessors to extended registers*/
  138. int ksz9031_phy_extended_write(struct phy_device *phydev,
  139. int devaddr, int regnum, u16 mode, u16 val)
  140. {
  141. /*select register addr for mmd*/
  142. phy_write(phydev, MDIO_DEVAD_NONE,
  143. MII_KSZ9031_MMD_ACCES_CTRL, devaddr);
  144. /*select register for mmd*/
  145. phy_write(phydev, MDIO_DEVAD_NONE,
  146. MII_KSZ9031_MMD_REG_DATA, regnum);
  147. /*setup mode*/
  148. phy_write(phydev, MDIO_DEVAD_NONE,
  149. MII_KSZ9031_MMD_ACCES_CTRL, (mode | devaddr));
  150. /*write the value*/
  151. return phy_write(phydev, MDIO_DEVAD_NONE,
  152. MII_KSZ9031_MMD_REG_DATA, val);
  153. }
  154. int ksz9031_phy_extended_read(struct phy_device *phydev, int devaddr,
  155. int regnum, u16 mode)
  156. {
  157. phy_write(phydev, MDIO_DEVAD_NONE,
  158. MII_KSZ9031_MMD_ACCES_CTRL, devaddr);
  159. phy_write(phydev, MDIO_DEVAD_NONE,
  160. MII_KSZ9031_MMD_REG_DATA, regnum);
  161. phy_write(phydev, MDIO_DEVAD_NONE,
  162. MII_KSZ9031_MMD_ACCES_CTRL, (devaddr | mode));
  163. return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9031_MMD_REG_DATA);
  164. }
  165. static int ksz9031_phy_extread(struct phy_device *phydev, int addr, int devaddr,
  166. int regnum)
  167. {
  168. return ksz9031_phy_extended_read(phydev, devaddr, regnum,
  169. MII_KSZ9031_MOD_DATA_NO_POST_INC);
  170. };
  171. static int ksz9031_phy_extwrite(struct phy_device *phydev, int addr,
  172. int devaddr, int regnum, u16 val)
  173. {
  174. return ksz9031_phy_extended_write(phydev, devaddr, regnum,
  175. MII_KSZ9031_MOD_DATA_POST_INC_RW, val);
  176. };
  177. static struct phy_driver ksz9031_driver = {
  178. .name = "Micrel ksz9031",
  179. .uid = 0x221620,
  180. .mask = 0xfffff0,
  181. .features = PHY_GBIT_FEATURES,
  182. .config = &genphy_config,
  183. .startup = &ksz90xx_startup,
  184. .shutdown = &genphy_shutdown,
  185. .writeext = &ksz9031_phy_extwrite,
  186. .readext = &ksz9031_phy_extread,
  187. };
  188. int phy_micrel_init(void)
  189. {
  190. phy_register(&KSZ804_driver);
  191. #ifdef CONFIG_PHY_MICREL_KSZ9021
  192. phy_register(&ksz9021_driver);
  193. #else
  194. phy_register(&KS8721_driver);
  195. #endif
  196. phy_register(&ksz9031_driver);
  197. return 0;
  198. }