micrel_ksz8xxx.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Micrel PHY drivers
  4. *
  5. * Copyright 2010-2011 Freescale Semiconductor, Inc.
  6. * author Andy Fleming
  7. * (C) 2012 NetModule AG, David Andrey, added KSZ9031
  8. */
  9. #include <common.h>
  10. #include <dm.h>
  11. #include <errno.h>
  12. #include <fdtdec.h>
  13. #include <micrel.h>
  14. #include <phy.h>
  15. static struct phy_driver KSZ804_driver = {
  16. .name = "Micrel KSZ804",
  17. .uid = 0x221510,
  18. .mask = 0xfffff0,
  19. .features = PHY_BASIC_FEATURES,
  20. .config = &genphy_config,
  21. .startup = &genphy_startup,
  22. .shutdown = &genphy_shutdown,
  23. };
  24. #define MII_KSZPHY_OMSO 0x16
  25. #define KSZPHY_OMSO_B_CAST_OFF (1 << 9)
  26. static int ksz_genconfig_bcastoff(struct phy_device *phydev)
  27. {
  28. int ret;
  29. ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZPHY_OMSO);
  30. if (ret < 0)
  31. return ret;
  32. ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZPHY_OMSO,
  33. ret | KSZPHY_OMSO_B_CAST_OFF);
  34. if (ret < 0)
  35. return ret;
  36. return genphy_config(phydev);
  37. }
  38. static struct phy_driver KSZ8031_driver = {
  39. .name = "Micrel KSZ8021/KSZ8031",
  40. .uid = 0x221550,
  41. .mask = 0xfffff0,
  42. .features = PHY_BASIC_FEATURES,
  43. .config = &ksz_genconfig_bcastoff,
  44. .startup = &genphy_startup,
  45. .shutdown = &genphy_shutdown,
  46. };
  47. /**
  48. * KSZ8051
  49. */
  50. #define MII_KSZ8051_PHY_OMSO 0x16
  51. #define MII_KSZ8051_PHY_OMSO_NAND_TREE_ON (1 << 5)
  52. static int ksz8051_config(struct phy_device *phydev)
  53. {
  54. unsigned val;
  55. /* Disable NAND-tree */
  56. val = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ8051_PHY_OMSO);
  57. val &= ~MII_KSZ8051_PHY_OMSO_NAND_TREE_ON;
  58. phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ8051_PHY_OMSO, val);
  59. return genphy_config(phydev);
  60. }
  61. static struct phy_driver KSZ8051_driver = {
  62. .name = "Micrel KSZ8051",
  63. .uid = 0x221550,
  64. .mask = 0xfffff0,
  65. .features = PHY_BASIC_FEATURES,
  66. .config = &ksz8051_config,
  67. .startup = &genphy_startup,
  68. .shutdown = &genphy_shutdown,
  69. };
  70. static struct phy_driver KSZ8081_driver = {
  71. .name = "Micrel KSZ8081",
  72. .uid = 0x221560,
  73. .mask = 0xfffff0,
  74. .features = PHY_BASIC_FEATURES,
  75. .config = &ksz_genconfig_bcastoff,
  76. .startup = &genphy_startup,
  77. .shutdown = &genphy_shutdown,
  78. };
  79. /**
  80. * KSZ8895
  81. */
  82. static unsigned short smireg_to_phy(unsigned short reg)
  83. {
  84. return ((reg & 0xc0) >> 3) + 0x06 + ((reg & 0x20) >> 5);
  85. }
  86. static unsigned short smireg_to_reg(unsigned short reg)
  87. {
  88. return reg & 0x1F;
  89. }
  90. static void ksz8895_write_smireg(struct phy_device *phydev, int smireg, int val)
  91. {
  92. phydev->bus->write(phydev->bus, smireg_to_phy(smireg), MDIO_DEVAD_NONE,
  93. smireg_to_reg(smireg), val);
  94. }
  95. #if 0
  96. static int ksz8895_read_smireg(struct phy_device *phydev, int smireg)
  97. {
  98. return phydev->bus->read(phydev->bus, smireg_to_phy(smireg),
  99. MDIO_DEVAD_NONE, smireg_to_reg(smireg));
  100. }
  101. #endif
  102. int ksz8895_config(struct phy_device *phydev)
  103. {
  104. /* we are connected directly to the switch without
  105. * dedicated PHY. SCONF1 == 001 */
  106. phydev->link = 1;
  107. phydev->duplex = DUPLEX_FULL;
  108. phydev->speed = SPEED_100;
  109. /* Force the switch to start */
  110. ksz8895_write_smireg(phydev, 1, 1);
  111. return 0;
  112. }
  113. static int ksz8895_startup(struct phy_device *phydev)
  114. {
  115. return 0;
  116. }
  117. static struct phy_driver ksz8895_driver = {
  118. .name = "Micrel KSZ8895/KSZ8864",
  119. .uid = 0x221450,
  120. .mask = 0xffffe1,
  121. .features = PHY_BASIC_FEATURES,
  122. .config = &ksz8895_config,
  123. .startup = &ksz8895_startup,
  124. .shutdown = &genphy_shutdown,
  125. };
  126. /* Micrel used the exact same part number for the KSZ9021. */
  127. static struct phy_driver KS8721_driver = {
  128. .name = "Micrel KS8721BL",
  129. .uid = 0x221610,
  130. .mask = 0xfffff0,
  131. .features = PHY_BASIC_FEATURES,
  132. .config = &genphy_config,
  133. .startup = &genphy_startup,
  134. .shutdown = &genphy_shutdown,
  135. };
  136. int ksz886x_config(struct phy_device *phydev)
  137. {
  138. /* we are connected directly to the switch without
  139. * dedicated PHY. */
  140. phydev->link = 1;
  141. phydev->duplex = DUPLEX_FULL;
  142. phydev->speed = SPEED_100;
  143. return 0;
  144. }
  145. static int ksz886x_startup(struct phy_device *phydev)
  146. {
  147. return 0;
  148. }
  149. static struct phy_driver ksz886x_driver = {
  150. .name = "Micrel KSZ886x Switch",
  151. .uid = 0x00221430,
  152. .mask = 0xfffff0,
  153. .features = PHY_BASIC_FEATURES,
  154. .config = &ksz886x_config,
  155. .startup = &ksz886x_startup,
  156. .shutdown = &genphy_shutdown,
  157. };
  158. int phy_micrel_ksz8xxx_init(void)
  159. {
  160. phy_register(&KSZ804_driver);
  161. phy_register(&KSZ8031_driver);
  162. phy_register(&KSZ8051_driver);
  163. phy_register(&KSZ8081_driver);
  164. phy_register(&KS8721_driver);
  165. phy_register(&ksz8895_driver);
  166. phy_register(&ksz886x_driver);
  167. return 0;
  168. }