micrel_ksz8xxx.c 4.3 KB

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