micrel.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  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. }
  260. return 0;
  261. }
  262. #else
  263. static int ksz9021_of_config(struct phy_device *phydev)
  264. {
  265. return 0;
  266. }
  267. #endif
  268. int ksz9021_phy_extended_write(struct phy_device *phydev, int regnum, u16 val)
  269. {
  270. /* extended registers */
  271. phy_write(phydev, MDIO_DEVAD_NONE,
  272. MII_KSZ9021_EXTENDED_CTRL, regnum | 0x8000);
  273. return phy_write(phydev, MDIO_DEVAD_NONE,
  274. MII_KSZ9021_EXTENDED_DATAW, val);
  275. }
  276. int ksz9021_phy_extended_read(struct phy_device *phydev, int regnum)
  277. {
  278. /* extended registers */
  279. phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_CTRL, regnum);
  280. return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_DATAR);
  281. }
  282. static int ksz9021_phy_extread(struct phy_device *phydev, int addr, int devaddr,
  283. int regnum)
  284. {
  285. return ksz9021_phy_extended_read(phydev, regnum);
  286. }
  287. static int ksz9021_phy_extwrite(struct phy_device *phydev, int addr,
  288. int devaddr, int regnum, u16 val)
  289. {
  290. return ksz9021_phy_extended_write(phydev, regnum, val);
  291. }
  292. /* Micrel ksz9021 */
  293. static int ksz9021_config(struct phy_device *phydev)
  294. {
  295. unsigned ctrl1000 = 0;
  296. const unsigned master = CTRL1000_PREFER_MASTER |
  297. CTRL1000_CONFIG_MASTER | CTRL1000_MANUAL_CONFIG;
  298. unsigned features = phydev->drv->features;
  299. int ret;
  300. ret = ksz9021_of_config(phydev);
  301. if (ret)
  302. return ret;
  303. if (getenv("disable_giga"))
  304. features &= ~(SUPPORTED_1000baseT_Half |
  305. SUPPORTED_1000baseT_Full);
  306. /* force master mode for 1000BaseT due to chip errata */
  307. if (features & SUPPORTED_1000baseT_Half)
  308. ctrl1000 |= ADVERTISE_1000HALF | master;
  309. if (features & SUPPORTED_1000baseT_Full)
  310. ctrl1000 |= ADVERTISE_1000FULL | master;
  311. phydev->advertising = phydev->supported = features;
  312. phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, ctrl1000);
  313. genphy_config_aneg(phydev);
  314. genphy_restart_aneg(phydev);
  315. return 0;
  316. }
  317. static struct phy_driver ksz9021_driver = {
  318. .name = "Micrel ksz9021",
  319. .uid = 0x221610,
  320. .mask = 0xfffff0,
  321. .features = PHY_GBIT_FEATURES,
  322. .config = &ksz9021_config,
  323. .startup = &ksz90xx_startup,
  324. .shutdown = &genphy_shutdown,
  325. .writeext = &ksz9021_phy_extwrite,
  326. .readext = &ksz9021_phy_extread,
  327. };
  328. #endif
  329. /**
  330. * KSZ9031
  331. */
  332. /* PHY Registers */
  333. #define MII_KSZ9031_MMD_ACCES_CTRL 0x0d
  334. #define MII_KSZ9031_MMD_REG_DATA 0x0e
  335. #if defined(CONFIG_DM_ETH) && (defined(CONFIG_PHY_MICREL_KSZ9021) || \
  336. defined(CONFIG_PHY_MICREL_KSZ9031))
  337. static const struct ksz90x1_reg_field ksz9031_ctl_grp[] =
  338. { { "txen-skew-ps", 4, 0, 0x7 }, { "rxdv-skew-ps", 4, 4, 0x7 } };
  339. static const struct ksz90x1_reg_field ksz9031_clk_grp[] =
  340. { { "rxc-skew-ps", 5, 0, 0xf }, { "txc-skew-ps", 5, 5, 0xf } };
  341. static int ksz9031_of_config(struct phy_device *phydev)
  342. {
  343. struct ksz90x1_ofcfg ofcfg[] = {
  344. { MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW, 2, ksz9031_ctl_grp, 2 },
  345. { MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW, 2, ksz90x1_rxd_grp, 4 },
  346. { MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW, 2, ksz90x1_txd_grp, 4 },
  347. { MII_KSZ9031_EXT_RGMII_CLOCK_SKEW, 2, ksz9031_clk_grp, 2 },
  348. };
  349. int i, ret = 0;
  350. for (i = 0; i < ARRAY_SIZE(ofcfg); i++) {
  351. ret = ksz90x1_of_config_group(phydev, &(ofcfg[i]));
  352. if (ret)
  353. return ret;
  354. }
  355. return 0;
  356. }
  357. static int ksz9031_center_flp_timing(struct phy_device *phydev)
  358. {
  359. struct phy_driver *drv = phydev->drv;
  360. int ret = 0;
  361. if (!drv || !drv->writeext)
  362. return -EOPNOTSUPP;
  363. ret = drv->writeext(phydev, 0, 0, MII_KSZ9031_FLP_BURST_TX_LO, 0x1A80);
  364. if (ret)
  365. return ret;
  366. ret = drv->writeext(phydev, 0, 0, MII_KSZ9031_FLP_BURST_TX_HI, 0x6);
  367. return ret;
  368. }
  369. #else
  370. static int ksz9031_of_config(struct phy_device *phydev)
  371. {
  372. return 0;
  373. }
  374. static int ksz9031_center_flp_timing(struct phy_device *phydev)
  375. {
  376. return 0;
  377. }
  378. #endif
  379. /* Accessors to extended registers*/
  380. int ksz9031_phy_extended_write(struct phy_device *phydev,
  381. int devaddr, int regnum, u16 mode, u16 val)
  382. {
  383. /*select register addr for mmd*/
  384. phy_write(phydev, MDIO_DEVAD_NONE,
  385. MII_KSZ9031_MMD_ACCES_CTRL, devaddr);
  386. /*select register for mmd*/
  387. phy_write(phydev, MDIO_DEVAD_NONE,
  388. MII_KSZ9031_MMD_REG_DATA, regnum);
  389. /*setup mode*/
  390. phy_write(phydev, MDIO_DEVAD_NONE,
  391. MII_KSZ9031_MMD_ACCES_CTRL, (mode | devaddr));
  392. /*write the value*/
  393. return phy_write(phydev, MDIO_DEVAD_NONE,
  394. MII_KSZ9031_MMD_REG_DATA, val);
  395. }
  396. int ksz9031_phy_extended_read(struct phy_device *phydev, int devaddr,
  397. int regnum, u16 mode)
  398. {
  399. phy_write(phydev, MDIO_DEVAD_NONE,
  400. MII_KSZ9031_MMD_ACCES_CTRL, devaddr);
  401. phy_write(phydev, MDIO_DEVAD_NONE,
  402. MII_KSZ9031_MMD_REG_DATA, regnum);
  403. phy_write(phydev, MDIO_DEVAD_NONE,
  404. MII_KSZ9031_MMD_ACCES_CTRL, (devaddr | mode));
  405. return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9031_MMD_REG_DATA);
  406. }
  407. static int ksz9031_phy_extread(struct phy_device *phydev, int addr, int devaddr,
  408. int regnum)
  409. {
  410. return ksz9031_phy_extended_read(phydev, devaddr, regnum,
  411. MII_KSZ9031_MOD_DATA_NO_POST_INC);
  412. };
  413. static int ksz9031_phy_extwrite(struct phy_device *phydev, int addr,
  414. int devaddr, int regnum, u16 val)
  415. {
  416. return ksz9031_phy_extended_write(phydev, devaddr, regnum,
  417. MII_KSZ9031_MOD_DATA_POST_INC_RW, val);
  418. };
  419. static int ksz9031_config(struct phy_device *phydev)
  420. {
  421. int ret;
  422. ret = ksz9031_of_config(phydev);
  423. if (ret)
  424. return ret;
  425. ret = ksz9031_center_flp_timing(phydev);
  426. if (ret)
  427. return ret;
  428. return genphy_config(phydev);
  429. }
  430. static struct phy_driver ksz9031_driver = {
  431. .name = "Micrel ksz9031",
  432. .uid = 0x221620,
  433. .mask = 0xfffff0,
  434. .features = PHY_GBIT_FEATURES,
  435. .config = &ksz9031_config,
  436. .startup = &ksz90xx_startup,
  437. .shutdown = &genphy_shutdown,
  438. .writeext = &ksz9031_phy_extwrite,
  439. .readext = &ksz9031_phy_extread,
  440. };
  441. int ksz886x_config(struct phy_device *phydev)
  442. {
  443. /* we are connected directly to the switch without
  444. * dedicated PHY. */
  445. phydev->link = 1;
  446. phydev->duplex = DUPLEX_FULL;
  447. phydev->speed = SPEED_100;
  448. return 0;
  449. }
  450. static int ksz886x_startup(struct phy_device *phydev)
  451. {
  452. return 0;
  453. }
  454. static struct phy_driver ksz886x_driver = {
  455. .name = "Micrel KSZ886x Switch",
  456. .uid = 0x00221430,
  457. .mask = 0xfffff0,
  458. .features = PHY_BASIC_FEATURES,
  459. .config = &ksz886x_config,
  460. .startup = &ksz886x_startup,
  461. .shutdown = &genphy_shutdown,
  462. };
  463. int phy_micrel_init(void)
  464. {
  465. phy_register(&KSZ804_driver);
  466. phy_register(&KSZ8031_driver);
  467. phy_register(&KSZ8051_driver);
  468. phy_register(&KSZ8081_driver);
  469. #ifdef CONFIG_PHY_MICREL_KSZ9021
  470. phy_register(&ksz9021_driver);
  471. #else
  472. phy_register(&KS8721_driver);
  473. #endif
  474. phy_register(&ksz9031_driver);
  475. phy_register(&ksz8895_driver);
  476. phy_register(&ksz886x_driver);
  477. return 0;
  478. }