micrel.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  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 <dm.h>
  13. #include <errno.h>
  14. #include <fdtdec.h>
  15. #include <micrel.h>
  16. #include <phy.h>
  17. DECLARE_GLOBAL_DATA_PTR;
  18. static struct phy_driver KSZ804_driver = {
  19. .name = "Micrel KSZ804",
  20. .uid = 0x221510,
  21. .mask = 0xfffff0,
  22. .features = PHY_BASIC_FEATURES,
  23. .config = &genphy_config,
  24. .startup = &genphy_startup,
  25. .shutdown = &genphy_shutdown,
  26. };
  27. #define MII_KSZPHY_OMSO 0x16
  28. #define KSZPHY_OMSO_B_CAST_OFF (1 << 9)
  29. static int ksz_genconfig_bcastoff(struct phy_device *phydev)
  30. {
  31. int ret;
  32. ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZPHY_OMSO);
  33. if (ret < 0)
  34. return ret;
  35. ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZPHY_OMSO,
  36. ret | KSZPHY_OMSO_B_CAST_OFF);
  37. if (ret < 0)
  38. return ret;
  39. return genphy_config(phydev);
  40. }
  41. static struct phy_driver KSZ8031_driver = {
  42. .name = "Micrel KSZ8021/KSZ8031",
  43. .uid = 0x221550,
  44. .mask = 0xfffff0,
  45. .features = PHY_BASIC_FEATURES,
  46. .config = &ksz_genconfig_bcastoff,
  47. .startup = &genphy_startup,
  48. .shutdown = &genphy_shutdown,
  49. };
  50. /**
  51. * KSZ8051
  52. */
  53. #define MII_KSZ8051_PHY_OMSO 0x16
  54. #define MII_KSZ8051_PHY_OMSO_NAND_TREE_ON (1 << 5)
  55. static int ksz8051_config(struct phy_device *phydev)
  56. {
  57. unsigned val;
  58. /* Disable NAND-tree */
  59. val = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ8051_PHY_OMSO);
  60. val &= ~MII_KSZ8051_PHY_OMSO_NAND_TREE_ON;
  61. phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ8051_PHY_OMSO, val);
  62. return genphy_config(phydev);
  63. }
  64. static struct phy_driver KSZ8051_driver = {
  65. .name = "Micrel KSZ8051",
  66. .uid = 0x221550,
  67. .mask = 0xfffff0,
  68. .features = PHY_BASIC_FEATURES,
  69. .config = &ksz8051_config,
  70. .startup = &genphy_startup,
  71. .shutdown = &genphy_shutdown,
  72. };
  73. static struct phy_driver KSZ8081_driver = {
  74. .name = "Micrel KSZ8081",
  75. .uid = 0x221560,
  76. .mask = 0xfffff0,
  77. .features = PHY_BASIC_FEATURES,
  78. .config = &ksz_genconfig_bcastoff,
  79. .startup = &genphy_startup,
  80. .shutdown = &genphy_shutdown,
  81. };
  82. /**
  83. * KSZ8895
  84. */
  85. static unsigned short smireg_to_phy(unsigned short reg)
  86. {
  87. return ((reg & 0xc0) >> 3) + 0x06 + ((reg & 0x20) >> 5);
  88. }
  89. static unsigned short smireg_to_reg(unsigned short reg)
  90. {
  91. return reg & 0x1F;
  92. }
  93. static void ksz8895_write_smireg(struct phy_device *phydev, int smireg, int val)
  94. {
  95. phydev->bus->write(phydev->bus, smireg_to_phy(smireg), MDIO_DEVAD_NONE,
  96. smireg_to_reg(smireg), val);
  97. }
  98. #if 0
  99. static int ksz8895_read_smireg(struct phy_device *phydev, int smireg)
  100. {
  101. return phydev->bus->read(phydev->bus, smireg_to_phy(smireg),
  102. MDIO_DEVAD_NONE, smireg_to_reg(smireg));
  103. }
  104. #endif
  105. int ksz8895_config(struct phy_device *phydev)
  106. {
  107. /* we are connected directly to the switch without
  108. * dedicated PHY. SCONF1 == 001 */
  109. phydev->link = 1;
  110. phydev->duplex = DUPLEX_FULL;
  111. phydev->speed = SPEED_100;
  112. /* Force the switch to start */
  113. ksz8895_write_smireg(phydev, 1, 1);
  114. return 0;
  115. }
  116. static int ksz8895_startup(struct phy_device *phydev)
  117. {
  118. return 0;
  119. }
  120. static struct phy_driver ksz8895_driver = {
  121. .name = "Micrel KSZ8895/KSZ8864",
  122. .uid = 0x221450,
  123. .mask = 0xffffe1,
  124. .features = PHY_BASIC_FEATURES,
  125. .config = &ksz8895_config,
  126. .startup = &ksz8895_startup,
  127. .shutdown = &genphy_shutdown,
  128. };
  129. #ifndef CONFIG_PHY_MICREL_KSZ9021
  130. /*
  131. * I can't believe Micrel used the exact same part number
  132. * for the KSZ9021. Shame Micrel, Shame!
  133. */
  134. static struct phy_driver KS8721_driver = {
  135. .name = "Micrel KS8721BL",
  136. .uid = 0x221610,
  137. .mask = 0xfffff0,
  138. .features = PHY_BASIC_FEATURES,
  139. .config = &genphy_config,
  140. .startup = &genphy_startup,
  141. .shutdown = &genphy_shutdown,
  142. };
  143. #endif
  144. /*
  145. * KSZ9021 - KSZ9031 common
  146. */
  147. #define MII_KSZ90xx_PHY_CTL 0x1f
  148. #define MIIM_KSZ90xx_PHYCTL_1000 (1 << 6)
  149. #define MIIM_KSZ90xx_PHYCTL_100 (1 << 5)
  150. #define MIIM_KSZ90xx_PHYCTL_10 (1 << 4)
  151. #define MIIM_KSZ90xx_PHYCTL_DUPLEX (1 << 3)
  152. static int ksz90xx_startup(struct phy_device *phydev)
  153. {
  154. unsigned phy_ctl;
  155. int ret;
  156. ret = genphy_update_link(phydev);
  157. if (ret)
  158. return ret;
  159. phy_ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ90xx_PHY_CTL);
  160. if (phy_ctl & MIIM_KSZ90xx_PHYCTL_DUPLEX)
  161. phydev->duplex = DUPLEX_FULL;
  162. else
  163. phydev->duplex = DUPLEX_HALF;
  164. if (phy_ctl & MIIM_KSZ90xx_PHYCTL_1000)
  165. phydev->speed = SPEED_1000;
  166. else if (phy_ctl & MIIM_KSZ90xx_PHYCTL_100)
  167. phydev->speed = SPEED_100;
  168. else if (phy_ctl & MIIM_KSZ90xx_PHYCTL_10)
  169. phydev->speed = SPEED_10;
  170. return 0;
  171. }
  172. /* Common OF config bits for KSZ9021 and KSZ9031 */
  173. #if defined(CONFIG_PHY_MICREL_KSZ9021) || defined(CONFIG_PHY_MICREL_KSZ9031)
  174. #ifdef CONFIG_DM_ETH
  175. struct ksz90x1_reg_field {
  176. const char *name;
  177. const u8 size; /* Size of the bitfield, in bits */
  178. const u8 off; /* Offset from bit 0 */
  179. const u8 dflt; /* Default value */
  180. };
  181. struct ksz90x1_ofcfg {
  182. const u16 reg;
  183. const u16 devad;
  184. const struct ksz90x1_reg_field *grp;
  185. const u16 grpsz;
  186. };
  187. static const struct ksz90x1_reg_field ksz90x1_rxd_grp[] = {
  188. { "rxd0-skew-ps", 4, 0, 0x7 }, { "rxd1-skew-ps", 4, 4, 0x7 },
  189. { "rxd2-skew-ps", 4, 8, 0x7 }, { "rxd3-skew-ps", 4, 12, 0x7 }
  190. };
  191. static const struct ksz90x1_reg_field ksz90x1_txd_grp[] = {
  192. { "txd0-skew-ps", 4, 0, 0x7 }, { "txd1-skew-ps", 4, 4, 0x7 },
  193. { "txd2-skew-ps", 4, 8, 0x7 }, { "txd3-skew-ps", 4, 12, 0x7 },
  194. };
  195. static int ksz90x1_of_config_group(struct phy_device *phydev,
  196. struct ksz90x1_ofcfg *ofcfg)
  197. {
  198. struct udevice *dev = phydev->dev;
  199. struct phy_driver *drv = phydev->drv;
  200. const int ps_to_regval = 60;
  201. int val[4];
  202. int i, changed = 0, offset, max;
  203. u16 regval = 0;
  204. if (!drv || !drv->writeext)
  205. return -EOPNOTSUPP;
  206. for (i = 0; i < ofcfg->grpsz; i++) {
  207. val[i] = fdtdec_get_uint(gd->fdt_blob, dev->of_offset,
  208. ofcfg->grp[i].name, -1);
  209. offset = ofcfg->grp[i].off;
  210. if (val[i] == -1) {
  211. /* Default register value for KSZ9021 */
  212. regval |= ofcfg->grp[i].dflt << offset;
  213. } else {
  214. changed = 1; /* Value was changed in OF */
  215. /* Calculate the register value and fix corner cases */
  216. if (val[i] > ps_to_regval * 0xf) {
  217. max = (1 << ofcfg->grp[i].size) - 1;
  218. regval |= max << offset;
  219. } else {
  220. regval |= (val[i] / ps_to_regval) << offset;
  221. }
  222. }
  223. }
  224. if (!changed)
  225. return 0;
  226. return drv->writeext(phydev, 0, ofcfg->devad, ofcfg->reg, regval);
  227. }
  228. #endif
  229. #endif
  230. #ifdef CONFIG_PHY_MICREL_KSZ9021
  231. /*
  232. * KSZ9021
  233. */
  234. /* PHY Registers */
  235. #define MII_KSZ9021_EXTENDED_CTRL 0x0b
  236. #define MII_KSZ9021_EXTENDED_DATAW 0x0c
  237. #define MII_KSZ9021_EXTENDED_DATAR 0x0d
  238. #define CTRL1000_PREFER_MASTER (1 << 10)
  239. #define CTRL1000_CONFIG_MASTER (1 << 11)
  240. #define CTRL1000_MANUAL_CONFIG (1 << 12)
  241. #if defined(CONFIG_DM_ETH) && (defined(CONFIG_PHY_MICREL_KSZ9021) || \
  242. defined(CONFIG_PHY_MICREL_KSZ9031))
  243. static const struct ksz90x1_reg_field ksz9021_clk_grp[] = {
  244. { "txen-skew-ps", 4, 0, 0x7 }, { "txc-skew-ps", 4, 4, 0x7 },
  245. { "rxdv-skew-ps", 4, 8, 0x7 }, { "rxc-skew-ps", 4, 12, 0x7 },
  246. };
  247. static int ksz9021_of_config(struct phy_device *phydev)
  248. {
  249. struct ksz90x1_ofcfg ofcfg[] = {
  250. { MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW, 0, ksz90x1_rxd_grp, 4 },
  251. { MII_KSZ9021_EXT_RGMII_TX_DATA_SKEW, 0, ksz90x1_txd_grp, 4 },
  252. { MII_KSZ9021_EXT_RGMII_CLOCK_SKEW, 0, ksz9021_clk_grp, 4 },
  253. };
  254. int i, ret = 0;
  255. for (i = 0; i < ARRAY_SIZE(ofcfg); i++)
  256. ret = ksz90x1_of_config_group(phydev, &(ofcfg[i]));
  257. if (ret)
  258. return ret;
  259. return 0;
  260. }
  261. #else
  262. static int ksz9021_of_config(struct phy_device *phydev)
  263. {
  264. return 0;
  265. }
  266. #endif
  267. int ksz9021_phy_extended_write(struct phy_device *phydev, int regnum, u16 val)
  268. {
  269. /* extended registers */
  270. phy_write(phydev, MDIO_DEVAD_NONE,
  271. MII_KSZ9021_EXTENDED_CTRL, regnum | 0x8000);
  272. return phy_write(phydev, MDIO_DEVAD_NONE,
  273. MII_KSZ9021_EXTENDED_DATAW, val);
  274. }
  275. int ksz9021_phy_extended_read(struct phy_device *phydev, int regnum)
  276. {
  277. /* extended registers */
  278. phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_CTRL, regnum);
  279. return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_DATAR);
  280. }
  281. static int ksz9021_phy_extread(struct phy_device *phydev, int addr, int devaddr,
  282. int regnum)
  283. {
  284. return ksz9021_phy_extended_read(phydev, regnum);
  285. }
  286. static int ksz9021_phy_extwrite(struct phy_device *phydev, int addr,
  287. int devaddr, int regnum, u16 val)
  288. {
  289. return ksz9021_phy_extended_write(phydev, regnum, val);
  290. }
  291. /* Micrel ksz9021 */
  292. static int ksz9021_config(struct phy_device *phydev)
  293. {
  294. unsigned ctrl1000 = 0;
  295. const unsigned master = CTRL1000_PREFER_MASTER |
  296. CTRL1000_CONFIG_MASTER | CTRL1000_MANUAL_CONFIG;
  297. unsigned features = phydev->drv->features;
  298. int ret;
  299. ret = ksz9021_of_config(phydev);
  300. if (ret)
  301. return ret;
  302. if (getenv("disable_giga"))
  303. features &= ~(SUPPORTED_1000baseT_Half |
  304. SUPPORTED_1000baseT_Full);
  305. /* force master mode for 1000BaseT due to chip errata */
  306. if (features & SUPPORTED_1000baseT_Half)
  307. ctrl1000 |= ADVERTISE_1000HALF | master;
  308. if (features & SUPPORTED_1000baseT_Full)
  309. ctrl1000 |= ADVERTISE_1000FULL | master;
  310. phydev->advertising = phydev->supported = features;
  311. phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, ctrl1000);
  312. genphy_config_aneg(phydev);
  313. genphy_restart_aneg(phydev);
  314. return 0;
  315. }
  316. static struct phy_driver ksz9021_driver = {
  317. .name = "Micrel ksz9021",
  318. .uid = 0x221610,
  319. .mask = 0xfffff0,
  320. .features = PHY_GBIT_FEATURES,
  321. .config = &ksz9021_config,
  322. .startup = &ksz90xx_startup,
  323. .shutdown = &genphy_shutdown,
  324. .writeext = &ksz9021_phy_extwrite,
  325. .readext = &ksz9021_phy_extread,
  326. };
  327. #endif
  328. /**
  329. * KSZ9031
  330. */
  331. /* PHY Registers */
  332. #define MII_KSZ9031_MMD_ACCES_CTRL 0x0d
  333. #define MII_KSZ9031_MMD_REG_DATA 0x0e
  334. #if defined(CONFIG_DM_ETH) && (defined(CONFIG_PHY_MICREL_KSZ9021) || \
  335. defined(CONFIG_PHY_MICREL_KSZ9031))
  336. static const struct ksz90x1_reg_field ksz9031_ctl_grp[] =
  337. { { "txen-skew-ps", 4, 0, 0x7 }, { "rxdv-skew-ps", 4, 4, 0x7 } };
  338. static const struct ksz90x1_reg_field ksz9031_clk_grp[] =
  339. { { "rxc-skew-ps", 5, 0, 0xf }, { "txc-skew-ps", 5, 5, 0xf } };
  340. static int ksz9031_of_config(struct phy_device *phydev)
  341. {
  342. struct ksz90x1_ofcfg ofcfg[] = {
  343. { MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW, 2, ksz9031_ctl_grp, 2 },
  344. { MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW, 2, ksz90x1_rxd_grp, 4 },
  345. { MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW, 2, ksz90x1_txd_grp, 4 },
  346. { MII_KSZ9031_EXT_RGMII_CLOCK_SKEW, 2, ksz9031_clk_grp, 2 },
  347. };
  348. int i, ret = 0;
  349. for (i = 0; i < ARRAY_SIZE(ofcfg); i++)
  350. ret = ksz90x1_of_config_group(phydev, &(ofcfg[i]));
  351. if (ret)
  352. return ret;
  353. return 0;
  354. }
  355. #else
  356. static int ksz9031_of_config(struct phy_device *phydev)
  357. {
  358. return 0;
  359. }
  360. #endif
  361. /* Accessors to extended registers*/
  362. int ksz9031_phy_extended_write(struct phy_device *phydev,
  363. int devaddr, int regnum, u16 mode, u16 val)
  364. {
  365. /*select register addr for mmd*/
  366. phy_write(phydev, MDIO_DEVAD_NONE,
  367. MII_KSZ9031_MMD_ACCES_CTRL, devaddr);
  368. /*select register for mmd*/
  369. phy_write(phydev, MDIO_DEVAD_NONE,
  370. MII_KSZ9031_MMD_REG_DATA, regnum);
  371. /*setup mode*/
  372. phy_write(phydev, MDIO_DEVAD_NONE,
  373. MII_KSZ9031_MMD_ACCES_CTRL, (mode | devaddr));
  374. /*write the value*/
  375. return phy_write(phydev, MDIO_DEVAD_NONE,
  376. MII_KSZ9031_MMD_REG_DATA, val);
  377. }
  378. int ksz9031_phy_extended_read(struct phy_device *phydev, int devaddr,
  379. int regnum, u16 mode)
  380. {
  381. phy_write(phydev, MDIO_DEVAD_NONE,
  382. MII_KSZ9031_MMD_ACCES_CTRL, devaddr);
  383. phy_write(phydev, MDIO_DEVAD_NONE,
  384. MII_KSZ9031_MMD_REG_DATA, regnum);
  385. phy_write(phydev, MDIO_DEVAD_NONE,
  386. MII_KSZ9031_MMD_ACCES_CTRL, (devaddr | mode));
  387. return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9031_MMD_REG_DATA);
  388. }
  389. static int ksz9031_phy_extread(struct phy_device *phydev, int addr, int devaddr,
  390. int regnum)
  391. {
  392. return ksz9031_phy_extended_read(phydev, devaddr, regnum,
  393. MII_KSZ9031_MOD_DATA_NO_POST_INC);
  394. };
  395. static int ksz9031_phy_extwrite(struct phy_device *phydev, int addr,
  396. int devaddr, int regnum, u16 val)
  397. {
  398. return ksz9031_phy_extended_write(phydev, devaddr, regnum,
  399. MII_KSZ9031_MOD_DATA_POST_INC_RW, val);
  400. };
  401. static int ksz9031_config(struct phy_device *phydev)
  402. {
  403. int ret;
  404. ret = ksz9031_of_config(phydev);
  405. if (ret)
  406. return ret;
  407. return genphy_config(phydev);
  408. }
  409. static struct phy_driver ksz9031_driver = {
  410. .name = "Micrel ksz9031",
  411. .uid = 0x221620,
  412. .mask = 0xfffff0,
  413. .features = PHY_GBIT_FEATURES,
  414. .config = &ksz9031_config,
  415. .startup = &ksz90xx_startup,
  416. .shutdown = &genphy_shutdown,
  417. .writeext = &ksz9031_phy_extwrite,
  418. .readext = &ksz9031_phy_extread,
  419. };
  420. int ksz886x_config(struct phy_device *phydev)
  421. {
  422. /* we are connected directly to the switch without
  423. * dedicated PHY. */
  424. phydev->link = 1;
  425. phydev->duplex = DUPLEX_FULL;
  426. phydev->speed = SPEED_100;
  427. return 0;
  428. }
  429. static int ksz886x_startup(struct phy_device *phydev)
  430. {
  431. return 0;
  432. }
  433. static struct phy_driver ksz886x_driver = {
  434. .name = "Micrel KSZ886x Switch",
  435. .uid = 0x00221430,
  436. .mask = 0xfffff0,
  437. .features = PHY_BASIC_FEATURES,
  438. .config = &ksz886x_config,
  439. .startup = &ksz886x_startup,
  440. .shutdown = &genphy_shutdown,
  441. };
  442. int phy_micrel_init(void)
  443. {
  444. phy_register(&KSZ804_driver);
  445. phy_register(&KSZ8031_driver);
  446. phy_register(&KSZ8051_driver);
  447. phy_register(&KSZ8081_driver);
  448. #ifdef CONFIG_PHY_MICREL_KSZ9021
  449. phy_register(&ksz9021_driver);
  450. #else
  451. phy_register(&KS8721_driver);
  452. #endif
  453. phy_register(&ksz9031_driver);
  454. phy_register(&ksz8895_driver);
  455. phy_register(&ksz886x_driver);
  456. return 0;
  457. }