motorcomm.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * RealTek PHY drivers
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  18. * MA 02111-1307 USA
  19. *
  20. * Copyright 2010-2011 Freescale Semiconductor, Inc.
  21. * author Andy Fleming
  22. *
  23. */
  24. #include <config.h>
  25. #include <common.h>
  26. #include <phy.h>
  27. #include <bitfield.h>
  28. #define REG_PHY_SPEC_STATUS 0x11
  29. #define REG_DEBUG_ADDR_OFFSET 0x1e
  30. #define REG_DEBUG_DATA 0x1f
  31. #define EXTREG_SLEEP_CONTROL 0x27
  32. #define YTPHY_EXTREG_CHIP_CONFIG 0xa001
  33. #define YTPHY_EXTREG_RGMII_CONFIG1 0xa003
  34. #define YTPHY_PAD_DRIVES_STRENGTH_CFG 0xa010
  35. #define YTPHY_DUPLEX 0x2000
  36. #define YTPHY_DUPLEX_BIT 13
  37. #define YTPHY_SPEED_MODE 0xc000
  38. #define YTPHY_SPEED_MODE_BIT 14
  39. #define YTPHY_RGMII_SW_DR_MASK GENMASK(5, 4)
  40. #define YTPHY_RGMII_RXC_DR_MASK GENMASK(15, 13)
  41. #define YT8521_EXT_CLK_GATE 0xc
  42. #define YT8521_EN_SLEEP_SW_BIT 15
  43. #define SPEED_UNKNOWN -1
  44. #define PHY_ID_YT8531 0x4f51e91b
  45. #define MOTORCOMM_PHY_ID_MASK 0x00000fff
  46. #define YT8512_EXTREG_LED0 0x40c0
  47. #define YT8512_EXTREG_LED1 0x40c3
  48. #define YT8512_EXTREG_SLEEP_CONTROL1 0x2027
  49. #define YT8512_LED0_ACT_BLK_IND 0x1000
  50. #define YT8512_LED0_DIS_LED_AN_TRY 0x0001
  51. #define YT8512_LED0_BT_BLK_EN 0x0002
  52. #define YT8512_LED0_HT_BLK_EN 0x0004
  53. #define YT8512_LED0_COL_BLK_EN 0x0008
  54. #define YT8512_LED0_BT_ON_EN 0x0010
  55. #define YT8512_LED1_BT_ON_EN 0x0010
  56. #define YT8512_LED1_TXACT_BLK_EN 0x0100
  57. #define YT8512_LED1_RXACT_BLK_EN 0x0200
  58. #define YT8512_EN_SLEEP_SW_BIT 15
  59. struct ytphy_reg_field {
  60. const char *name;
  61. const u8 size; /* Size of the bitfield, in bits */
  62. const u8 off; /* Offset from bit 0 */
  63. const u8 dflt; /* Default value */
  64. };
  65. static const struct ytphy_reg_field ytphy_dr_grp[] = {
  66. { "rgmii_sw_dr", 2, 4, 0x3},
  67. { "rgmii_sw_dr_2", 1, 12, 0x0},
  68. { "rgmii_sw_dr_rxc", 3, 13, 0x3}
  69. };
  70. static const struct ytphy_reg_field ytphy_rxtxd_grp[] = {
  71. { "rx_delay_sel", 4, 10, 0x0 },
  72. { "tx_delay_sel_fe", 4, 4, 0xf },
  73. { "tx_delay_sel", 4, 0, 0x1 }
  74. };
  75. static const struct ytphy_reg_field ytphy_txinver_grp[] = {
  76. { "tx_inverted_1000", 1, 14, 0x0 },
  77. { "tx_inverted_100", 1, 14, 0x0 },
  78. { "tx_inverted_10", 1, 14, 0x0 }
  79. };
  80. static const struct ytphy_reg_field ytphy_rxden_grp[] = {
  81. { "rxc_dly_en", 1, 8, 0x1 }
  82. };
  83. static int ytphy_of_config(struct phy_device *phydev);
  84. static int ytphy_read_ext(struct phy_device *phydev, u32 regnum)
  85. {
  86. int ret;
  87. ret = phy_write(phydev, MDIO_DEVAD_NONE, REG_DEBUG_ADDR_OFFSET, regnum);
  88. if (ret < 0)
  89. return ret;
  90. return phy_read(phydev, MDIO_DEVAD_NONE, REG_DEBUG_DATA);
  91. }
  92. static int ytphy_write_ext(struct phy_device *phydev, u32 regnum, u16 val)
  93. {
  94. int ret;
  95. ret = phy_write(phydev, MDIO_DEVAD_NONE, REG_DEBUG_ADDR_OFFSET, regnum);
  96. if (ret < 0)
  97. return ret;
  98. return phy_write(phydev, MDIO_DEVAD_NONE, REG_DEBUG_DATA, val);
  99. }
  100. static int ytphy_parse_status(struct phy_device *phydev)
  101. {
  102. int val;
  103. int speed, speed_mode, duplex;
  104. val = phy_read(phydev, MDIO_DEVAD_NONE, REG_PHY_SPEC_STATUS);
  105. if (val < 0)
  106. return val;
  107. duplex = (val & YTPHY_DUPLEX) >> YTPHY_DUPLEX_BIT;
  108. speed_mode = (val & YTPHY_SPEED_MODE) >> YTPHY_SPEED_MODE_BIT;
  109. switch (speed_mode) {
  110. case 2:
  111. speed = SPEED_1000;
  112. break;
  113. case 1:
  114. speed = SPEED_100;
  115. break;
  116. default:
  117. speed = SPEED_10;
  118. break;
  119. }
  120. phydev->speed = speed;
  121. phydev->duplex = duplex;
  122. return 0;
  123. }
  124. static int ytphy_of_inverted(struct phy_device *phydev)
  125. {
  126. ofnode node;
  127. u32 val;
  128. u32 inver_10;
  129. u32 inver_100;
  130. u32 inver_1000;
  131. node = phydev->node;
  132. if (!ofnode_valid(node)) {
  133. /* Look for a PHY node under the Ethernet node */
  134. node = dev_read_subnode(phydev->dev, "ethernet-phy");
  135. }
  136. if (!ofnode_valid(node)) /* No node found*/
  137. return 0;
  138. val = ytphy_read_ext(phydev, YTPHY_EXTREG_RGMII_CONFIG1);
  139. inver_10 = ofnode_read_u32_default(node, "tx_inverted_10", 0);
  140. inver_100 = ofnode_read_u32_default(node, "tx_inverted_100", 0);
  141. inver_1000 = ofnode_read_u32_default(node, "tx_inverted_1000", 0);
  142. switch (phydev->speed) {
  143. case SPEED_1000:
  144. val = bitfield_replace(val, ytphy_txinver_grp[0].off,
  145. ytphy_txinver_grp[0].size, inver_1000);
  146. break;
  147. case SPEED_100:
  148. val = bitfield_replace(val, ytphy_txinver_grp[1].off,
  149. ytphy_txinver_grp[1].size, inver_100);
  150. break;
  151. case SPEED_10:
  152. val = bitfield_replace(val, ytphy_txinver_grp[2].off,
  153. ytphy_txinver_grp[2].size, inver_10);
  154. break;
  155. default:
  156. printf("UNKOWN SPEED\n");
  157. break;
  158. }
  159. return ytphy_write_ext(phydev, YTPHY_EXTREG_RGMII_CONFIG1, val);
  160. }
  161. static int ytphy_startup(struct phy_device *phydev)
  162. {
  163. int retval;
  164. /*set delay config*/
  165. retval = ytphy_of_config(phydev);
  166. if (retval < 0)
  167. return retval;
  168. retval = genphy_update_link(phydev);
  169. if (retval)
  170. return retval;
  171. ytphy_parse_status(phydev);
  172. ytphy_of_inverted(phydev);
  173. return 0;
  174. }
  175. static int ytphy_of_config(struct phy_device *phydev)
  176. {
  177. ofnode node;
  178. u32 val;
  179. u32 cfg;
  180. int i;
  181. node = phydev->node;
  182. if (!ofnode_valid(node)) {
  183. /* Look for a PHY node under the Ethernet node */
  184. node = dev_read_subnode(phydev->dev, "ethernet-phy");
  185. }
  186. if (!ofnode_valid(node)) /* No node found*/
  187. return 0;
  188. /*read rxc_dly_en config*/
  189. cfg = ofnode_read_u32_default(node, ytphy_rxden_grp[0].name, ~0);
  190. if (cfg != -1) {
  191. val = ytphy_read_ext(phydev, YTPHY_EXTREG_CHIP_CONFIG);
  192. /*check the cfg overflow or not*/
  193. cfg = (cfg > ((1 << ytphy_rxden_grp[0].size) - 1)) ?
  194. ((1 << ytphy_rxden_grp[0].size) - 1) : cfg;
  195. val = bitfield_replace(val, ytphy_rxden_grp[0].off,
  196. ytphy_rxden_grp[0].size, cfg);
  197. ytphy_write_ext(phydev, YTPHY_EXTREG_CHIP_CONFIG, val);
  198. }
  199. val = ytphy_read_ext(phydev, YTPHY_PAD_DRIVES_STRENGTH_CFG);
  200. for (i = 0; i < ARRAY_SIZE(ytphy_dr_grp); i++) {
  201. cfg = ofnode_read_u32_default(node,
  202. ytphy_dr_grp[i].name, ~0);
  203. cfg = (cfg != -1) ? cfg : ytphy_dr_grp[i].dflt;
  204. /*check the cfg overflow or not*/
  205. cfg = (cfg > ((1 << ytphy_dr_grp[i].size) - 1)) ?
  206. ((1 << ytphy_dr_grp[i].size) - 1) : cfg;
  207. val = bitfield_replace(val, ytphy_dr_grp[i].off,
  208. ytphy_dr_grp[i].size, cfg);
  209. }
  210. ytphy_write_ext(phydev, YTPHY_PAD_DRIVES_STRENGTH_CFG, val);
  211. val = ytphy_read_ext(phydev, YTPHY_EXTREG_RGMII_CONFIG1);
  212. for (i = 0; i < ARRAY_SIZE(ytphy_rxtxd_grp); i++) {
  213. cfg = ofnode_read_u32_default(node,
  214. ytphy_rxtxd_grp[i].name, ~0);
  215. cfg = (cfg != -1) ? cfg : ytphy_rxtxd_grp[i].dflt;
  216. /*check the cfg overflow or not*/
  217. cfg = (cfg > ((1 << ytphy_rxtxd_grp[i].size) - 1)) ?
  218. ((1 << ytphy_rxtxd_grp[i].size) - 1) : cfg;
  219. val = bitfield_replace(val, ytphy_rxtxd_grp[i].off,
  220. ytphy_rxtxd_grp[i].size, cfg);
  221. }
  222. return ytphy_write_ext(phydev, YTPHY_EXTREG_RGMII_CONFIG1, val);
  223. }
  224. static int yt8512_led_init(struct phy_device *phydev)
  225. {
  226. int ret;
  227. int val;
  228. int mask;
  229. val = ytphy_read_ext(phydev, YT8512_EXTREG_LED0);
  230. if (val < 0)
  231. return val;
  232. val |= YT8512_LED0_ACT_BLK_IND;
  233. mask = YT8512_LED0_DIS_LED_AN_TRY | YT8512_LED0_BT_BLK_EN |
  234. YT8512_LED0_HT_BLK_EN | YT8512_LED0_COL_BLK_EN |
  235. YT8512_LED0_BT_ON_EN;
  236. val &= ~mask;
  237. ret = ytphy_write_ext(phydev, YT8512_EXTREG_LED0, val);
  238. if (ret < 0)
  239. return ret;
  240. val = ytphy_read_ext(phydev, YT8512_EXTREG_LED1);
  241. if (val < 0)
  242. return val;
  243. val |= YT8512_LED1_BT_ON_EN;
  244. mask = YT8512_LED1_TXACT_BLK_EN | YT8512_LED1_RXACT_BLK_EN;
  245. val &= ~mask;
  246. ret = ytphy_write_ext(phydev, YT8512_LED1_BT_ON_EN, val);
  247. return ret;
  248. }
  249. static int yt8512_config(struct phy_device *phydev)
  250. {
  251. int ret;
  252. int val;
  253. ret = 0;
  254. genphy_config_aneg(phydev);
  255. ret = yt8512_led_init(phydev);
  256. /* disable auto sleep */
  257. val = ytphy_read_ext(phydev, YT8512_EXTREG_SLEEP_CONTROL1);
  258. if (val < 0)
  259. return val;
  260. val &= (~BIT(YT8512_EN_SLEEP_SW_BIT));
  261. ret = ytphy_write_ext(phydev, YT8512_EXTREG_SLEEP_CONTROL1, val);
  262. if (ret < 0)
  263. return ret;
  264. return ret;
  265. }
  266. static int yt8521_config(struct phy_device *phydev)
  267. {
  268. int ret, val;
  269. ret = 0;
  270. genphy_config_aneg(phydev);
  271. /* disable auto sleep */
  272. val = ytphy_read_ext(phydev, EXTREG_SLEEP_CONTROL);
  273. if (val < 0)
  274. return val;
  275. val &= ~(1 << YT8521_EN_SLEEP_SW_BIT);
  276. ret = ytphy_write_ext(phydev, EXTREG_SLEEP_CONTROL, val);
  277. if (ret < 0)
  278. return ret;
  279. /*set delay config*/
  280. ret = ytphy_of_config(phydev);
  281. if (ret < 0)
  282. return ret;
  283. val = ytphy_read_ext(phydev, YT8521_EXT_CLK_GATE);
  284. if (val < 0)
  285. return val;
  286. val &= ~(1 << 12);
  287. ret = ytphy_write_ext(phydev, YT8521_EXT_CLK_GATE, val);
  288. if (ret < 0)
  289. return ret;
  290. return 0;
  291. }
  292. static int yt8531_config(struct phy_device *phydev)
  293. {
  294. int ret;
  295. ret = 0;
  296. genphy_config_aneg(phydev);
  297. return 0;
  298. }
  299. static struct phy_driver YT8512_driver = {
  300. .name = "YuTai YT8512",
  301. .uid = 0x00000118,
  302. .mask = 0x00000fff,
  303. .features = PHY_GBIT_FEATURES,
  304. .config = &yt8512_config,
  305. .startup = &ytphy_startup,
  306. .shutdown = &genphy_shutdown,
  307. };
  308. static struct phy_driver YT8521_driver = {
  309. .name = "YuTai YT8521",
  310. .uid = 0x0000011a,
  311. .mask = 0x00000fff,
  312. .features = PHY_GBIT_FEATURES,
  313. .config = &yt8521_config,
  314. .startup = &ytphy_startup,
  315. .shutdown = &genphy_shutdown,
  316. };
  317. static struct phy_driver YT8531_driver = {
  318. .name = "YT8531 Gigabit Ethernet",
  319. .uid = PHY_ID_YT8531,
  320. .mask = MOTORCOMM_PHY_ID_MASK,
  321. .features = PHY_GBIT_FEATURES,
  322. .config = &yt8531_config,
  323. .startup = &ytphy_startup,
  324. .shutdown = &genphy_shutdown,
  325. };
  326. int phy_yutai_init(void)
  327. {
  328. phy_register(&YT8512_driver);
  329. phy_register(&YT8521_driver);
  330. phy_register(&YT8531_driver);
  331. return 0;
  332. }