micrel.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  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. static struct phy_driver KSZ8081_driver = {
  24. .name = "Micrel KSZ8081",
  25. .uid = 0x221560,
  26. .mask = 0xfffff0,
  27. .features = PHY_BASIC_FEATURES,
  28. .config = &genphy_config,
  29. .startup = &genphy_startup,
  30. .shutdown = &genphy_shutdown,
  31. };
  32. /**
  33. * KSZ8895
  34. */
  35. static unsigned short smireg_to_phy(unsigned short reg)
  36. {
  37. return ((reg & 0xc0) >> 3) + 0x06 + ((reg & 0x20) >> 5);
  38. }
  39. static unsigned short smireg_to_reg(unsigned short reg)
  40. {
  41. return reg & 0x1F;
  42. }
  43. static void ksz8895_write_smireg(struct phy_device *phydev, int smireg, int val)
  44. {
  45. phydev->bus->write(phydev->bus, smireg_to_phy(smireg), MDIO_DEVAD_NONE,
  46. smireg_to_reg(smireg), val);
  47. }
  48. #if 0
  49. static int ksz8895_read_smireg(struct phy_device *phydev, int smireg)
  50. {
  51. return phydev->bus->read(phydev->bus, smireg_to_phy(smireg),
  52. MDIO_DEVAD_NONE, smireg_to_reg(smireg));
  53. }
  54. #endif
  55. int ksz8895_config(struct phy_device *phydev)
  56. {
  57. /* we are connected directly to the switch without
  58. * dedicated PHY. SCONF1 == 001 */
  59. phydev->link = 1;
  60. phydev->duplex = DUPLEX_FULL;
  61. phydev->speed = SPEED_100;
  62. /* Force the switch to start */
  63. ksz8895_write_smireg(phydev, 1, 1);
  64. return 0;
  65. }
  66. static int ksz8895_startup(struct phy_device *phydev)
  67. {
  68. return 0;
  69. }
  70. static struct phy_driver ksz8895_driver = {
  71. .name = "Micrel KSZ8895/KSZ8864",
  72. .uid = 0x221450,
  73. .mask = 0xffffe1,
  74. .features = PHY_BASIC_FEATURES,
  75. .config = &ksz8895_config,
  76. .startup = &ksz8895_startup,
  77. .shutdown = &genphy_shutdown,
  78. };
  79. #ifndef CONFIG_PHY_MICREL_KSZ9021
  80. /*
  81. * I can't believe Micrel used the exact same part number
  82. * for the KSZ9021. Shame Micrel, Shame!
  83. */
  84. static struct phy_driver KS8721_driver = {
  85. .name = "Micrel KS8721BL",
  86. .uid = 0x221610,
  87. .mask = 0xfffff0,
  88. .features = PHY_BASIC_FEATURES,
  89. .config = &genphy_config,
  90. .startup = &genphy_startup,
  91. .shutdown = &genphy_shutdown,
  92. };
  93. #endif
  94. /*
  95. * KSZ9021 - KSZ9031 common
  96. */
  97. #define MII_KSZ90xx_PHY_CTL 0x1f
  98. #define MIIM_KSZ90xx_PHYCTL_1000 (1 << 6)
  99. #define MIIM_KSZ90xx_PHYCTL_100 (1 << 5)
  100. #define MIIM_KSZ90xx_PHYCTL_10 (1 << 4)
  101. #define MIIM_KSZ90xx_PHYCTL_DUPLEX (1 << 3)
  102. static int ksz90xx_startup(struct phy_device *phydev)
  103. {
  104. unsigned phy_ctl;
  105. genphy_update_link(phydev);
  106. phy_ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ90xx_PHY_CTL);
  107. if (phy_ctl & MIIM_KSZ90xx_PHYCTL_DUPLEX)
  108. phydev->duplex = DUPLEX_FULL;
  109. else
  110. phydev->duplex = DUPLEX_HALF;
  111. if (phy_ctl & MIIM_KSZ90xx_PHYCTL_1000)
  112. phydev->speed = SPEED_1000;
  113. else if (phy_ctl & MIIM_KSZ90xx_PHYCTL_100)
  114. phydev->speed = SPEED_100;
  115. else if (phy_ctl & MIIM_KSZ90xx_PHYCTL_10)
  116. phydev->speed = SPEED_10;
  117. return 0;
  118. }
  119. #ifdef CONFIG_PHY_MICREL_KSZ9021
  120. /*
  121. * KSZ9021
  122. */
  123. /* PHY Registers */
  124. #define MII_KSZ9021_EXTENDED_CTRL 0x0b
  125. #define MII_KSZ9021_EXTENDED_DATAW 0x0c
  126. #define MII_KSZ9021_EXTENDED_DATAR 0x0d
  127. #define CTRL1000_PREFER_MASTER (1 << 10)
  128. #define CTRL1000_CONFIG_MASTER (1 << 11)
  129. #define CTRL1000_MANUAL_CONFIG (1 << 12)
  130. int ksz9021_phy_extended_write(struct phy_device *phydev, int regnum, u16 val)
  131. {
  132. /* extended registers */
  133. phy_write(phydev, MDIO_DEVAD_NONE,
  134. MII_KSZ9021_EXTENDED_CTRL, regnum | 0x8000);
  135. return phy_write(phydev, MDIO_DEVAD_NONE,
  136. MII_KSZ9021_EXTENDED_DATAW, val);
  137. }
  138. int ksz9021_phy_extended_read(struct phy_device *phydev, int regnum)
  139. {
  140. /* extended registers */
  141. phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_CTRL, regnum);
  142. return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_DATAR);
  143. }
  144. static int ksz9021_phy_extread(struct phy_device *phydev, int addr, int devaddr,
  145. int regnum)
  146. {
  147. return ksz9021_phy_extended_read(phydev, regnum);
  148. }
  149. static int ksz9021_phy_extwrite(struct phy_device *phydev, int addr,
  150. int devaddr, int regnum, u16 val)
  151. {
  152. return ksz9021_phy_extended_write(phydev, regnum, val);
  153. }
  154. /* Micrel ksz9021 */
  155. static int ksz9021_config(struct phy_device *phydev)
  156. {
  157. unsigned ctrl1000 = 0;
  158. const unsigned master = CTRL1000_PREFER_MASTER |
  159. CTRL1000_CONFIG_MASTER | CTRL1000_MANUAL_CONFIG;
  160. unsigned features = phydev->drv->features;
  161. if (getenv("disable_giga"))
  162. features &= ~(SUPPORTED_1000baseT_Half |
  163. SUPPORTED_1000baseT_Full);
  164. /* force master mode for 1000BaseT due to chip errata */
  165. if (features & SUPPORTED_1000baseT_Half)
  166. ctrl1000 |= ADVERTISE_1000HALF | master;
  167. if (features & SUPPORTED_1000baseT_Full)
  168. ctrl1000 |= ADVERTISE_1000FULL | master;
  169. phydev->advertising = phydev->supported = features;
  170. phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, ctrl1000);
  171. genphy_config_aneg(phydev);
  172. genphy_restart_aneg(phydev);
  173. return 0;
  174. }
  175. static struct phy_driver ksz9021_driver = {
  176. .name = "Micrel ksz9021",
  177. .uid = 0x221610,
  178. .mask = 0xfffff0,
  179. .features = PHY_GBIT_FEATURES,
  180. .config = &ksz9021_config,
  181. .startup = &ksz90xx_startup,
  182. .shutdown = &genphy_shutdown,
  183. .writeext = &ksz9021_phy_extwrite,
  184. .readext = &ksz9021_phy_extread,
  185. };
  186. #endif
  187. /**
  188. * KSZ9031
  189. */
  190. /* PHY Registers */
  191. #define MII_KSZ9031_MMD_ACCES_CTRL 0x0d
  192. #define MII_KSZ9031_MMD_REG_DATA 0x0e
  193. /* Accessors to extended registers*/
  194. int ksz9031_phy_extended_write(struct phy_device *phydev,
  195. int devaddr, int regnum, u16 mode, u16 val)
  196. {
  197. /*select register addr for mmd*/
  198. phy_write(phydev, MDIO_DEVAD_NONE,
  199. MII_KSZ9031_MMD_ACCES_CTRL, devaddr);
  200. /*select register for mmd*/
  201. phy_write(phydev, MDIO_DEVAD_NONE,
  202. MII_KSZ9031_MMD_REG_DATA, regnum);
  203. /*setup mode*/
  204. phy_write(phydev, MDIO_DEVAD_NONE,
  205. MII_KSZ9031_MMD_ACCES_CTRL, (mode | devaddr));
  206. /*write the value*/
  207. return phy_write(phydev, MDIO_DEVAD_NONE,
  208. MII_KSZ9031_MMD_REG_DATA, val);
  209. }
  210. int ksz9031_phy_extended_read(struct phy_device *phydev, int devaddr,
  211. int regnum, u16 mode)
  212. {
  213. phy_write(phydev, MDIO_DEVAD_NONE,
  214. MII_KSZ9031_MMD_ACCES_CTRL, devaddr);
  215. phy_write(phydev, MDIO_DEVAD_NONE,
  216. MII_KSZ9031_MMD_REG_DATA, regnum);
  217. phy_write(phydev, MDIO_DEVAD_NONE,
  218. MII_KSZ9031_MMD_ACCES_CTRL, (devaddr | mode));
  219. return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9031_MMD_REG_DATA);
  220. }
  221. static int ksz9031_phy_extread(struct phy_device *phydev, int addr, int devaddr,
  222. int regnum)
  223. {
  224. return ksz9031_phy_extended_read(phydev, devaddr, regnum,
  225. MII_KSZ9031_MOD_DATA_NO_POST_INC);
  226. };
  227. static int ksz9031_phy_extwrite(struct phy_device *phydev, int addr,
  228. int devaddr, int regnum, u16 val)
  229. {
  230. return ksz9031_phy_extended_write(phydev, devaddr, regnum,
  231. MII_KSZ9031_MOD_DATA_POST_INC_RW, val);
  232. };
  233. static struct phy_driver ksz9031_driver = {
  234. .name = "Micrel ksz9031",
  235. .uid = 0x221620,
  236. .mask = 0xfffff0,
  237. .features = PHY_GBIT_FEATURES,
  238. .config = &genphy_config,
  239. .startup = &ksz90xx_startup,
  240. .shutdown = &genphy_shutdown,
  241. .writeext = &ksz9031_phy_extwrite,
  242. .readext = &ksz9031_phy_extread,
  243. };
  244. int phy_micrel_init(void)
  245. {
  246. phy_register(&KSZ804_driver);
  247. phy_register(&KSZ8081_driver);
  248. #ifdef CONFIG_PHY_MICREL_KSZ9021
  249. phy_register(&ksz9021_driver);
  250. #else
  251. phy_register(&KS8721_driver);
  252. #endif
  253. phy_register(&ksz9031_driver);
  254. phy_register(&ksz8895_driver);
  255. return 0;
  256. }