marvell-88q2xxx.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Marvell 88Q2XXX automotive 100BASE-T1/1000BASE-T1 PHY driver
  4. *
  5. * Derived from Marvell Q222x API
  6. *
  7. * Copyright (C) 2024 Liebherr-Electronics and Drives GmbH
  8. */
  9. #include <linux/ethtool_netlink.h>
  10. #include <linux/marvell_phy.h>
  11. #include <linux/phy.h>
  12. #include <linux/hwmon.h>
  13. #define PHY_ID_88Q2220_REVB0 (MARVELL_PHY_ID_88Q2220 | 0x1)
  14. #define PHY_ID_88Q2220_REVB1 (MARVELL_PHY_ID_88Q2220 | 0x2)
  15. #define PHY_ID_88Q2220_REVB2 (MARVELL_PHY_ID_88Q2220 | 0x3)
  16. #define MDIO_MMD_AN_MV_STAT 32769
  17. #define MDIO_MMD_AN_MV_STAT_ANEG 0x0100
  18. #define MDIO_MMD_AN_MV_STAT_LOCAL_RX 0x1000
  19. #define MDIO_MMD_AN_MV_STAT_REMOTE_RX 0x2000
  20. #define MDIO_MMD_AN_MV_STAT_LOCAL_MASTER 0x4000
  21. #define MDIO_MMD_AN_MV_STAT_MS_CONF_FAULT 0x8000
  22. #define MDIO_MMD_AN_MV_STAT2 32794
  23. #define MDIO_MMD_AN_MV_STAT2_AN_RESOLVED 0x0800
  24. #define MDIO_MMD_AN_MV_STAT2_100BT1 0x2000
  25. #define MDIO_MMD_AN_MV_STAT2_1000BT1 0x4000
  26. #define MDIO_MMD_PCS_MV_INT_EN 32784
  27. #define MDIO_MMD_PCS_MV_INT_EN_LINK_UP 0x0040
  28. #define MDIO_MMD_PCS_MV_INT_EN_LINK_DOWN 0x0080
  29. #define MDIO_MMD_PCS_MV_INT_EN_100BT1 0x1000
  30. #define MDIO_MMD_PCS_MV_GPIO_INT_STAT 32785
  31. #define MDIO_MMD_PCS_MV_GPIO_INT_STAT_LINK_UP 0x0040
  32. #define MDIO_MMD_PCS_MV_GPIO_INT_STAT_LINK_DOWN 0x0080
  33. #define MDIO_MMD_PCS_MV_GPIO_INT_STAT_100BT1_GEN 0x1000
  34. #define MDIO_MMD_PCS_MV_GPIO_INT_CTRL 32787
  35. #define MDIO_MMD_PCS_MV_GPIO_INT_CTRL_TRI_DIS 0x0800
  36. #define MDIO_MMD_PCS_MV_TEMP_SENSOR1 32833
  37. #define MDIO_MMD_PCS_MV_TEMP_SENSOR1_RAW_INT 0x0001
  38. #define MDIO_MMD_PCS_MV_TEMP_SENSOR1_INT 0x0040
  39. #define MDIO_MMD_PCS_MV_TEMP_SENSOR1_INT_EN 0x0080
  40. #define MDIO_MMD_PCS_MV_TEMP_SENSOR2 32834
  41. #define MDIO_MMD_PCS_MV_TEMP_SENSOR2_DIS_MASK 0xc000
  42. #define MDIO_MMD_PCS_MV_TEMP_SENSOR3 32835
  43. #define MDIO_MMD_PCS_MV_TEMP_SENSOR3_INT_THRESH_MASK 0xff00
  44. #define MDIO_MMD_PCS_MV_TEMP_SENSOR3_MASK 0x00ff
  45. #define MDIO_MMD_PCS_MV_100BT1_STAT1 33032
  46. #define MDIO_MMD_PCS_MV_100BT1_STAT1_IDLE_ERROR 0x00ff
  47. #define MDIO_MMD_PCS_MV_100BT1_STAT1_JABBER 0x0100
  48. #define MDIO_MMD_PCS_MV_100BT1_STAT1_LINK 0x0200
  49. #define MDIO_MMD_PCS_MV_100BT1_STAT1_LOCAL_RX 0x1000
  50. #define MDIO_MMD_PCS_MV_100BT1_STAT1_REMOTE_RX 0x2000
  51. #define MDIO_MMD_PCS_MV_100BT1_STAT1_LOCAL_MASTER 0x4000
  52. #define MDIO_MMD_PCS_MV_100BT1_STAT2 33033
  53. #define MDIO_MMD_PCS_MV_100BT1_STAT2_JABBER 0x0001
  54. #define MDIO_MMD_PCS_MV_100BT1_STAT2_POL 0x0002
  55. #define MDIO_MMD_PCS_MV_100BT1_STAT2_LINK 0x0004
  56. #define MDIO_MMD_PCS_MV_100BT1_STAT2_ANGE 0x0008
  57. #define MDIO_MMD_PCS_MV_100BT1_INT_EN 33042
  58. #define MDIO_MMD_PCS_MV_100BT1_INT_EN_LINKEVENT 0x0400
  59. #define MDIO_MMD_PCS_MV_COPPER_INT_STAT 33043
  60. #define MDIO_MMD_PCS_MV_COPPER_INT_STAT_LINKEVENT 0x0400
  61. #define MDIO_MMD_PCS_MV_RX_STAT 33328
  62. #define MDIO_MMD_PCS_MV_TDR_RESET 65226
  63. #define MDIO_MMD_PCS_MV_TDR_RESET_TDR_RST 0x1000
  64. #define MDIO_MMD_PCS_MV_TDR_OFF_SHORT_CABLE 65241
  65. #define MDIO_MMD_PCS_MV_TDR_OFF_LONG_CABLE 65242
  66. #define MDIO_MMD_PCS_MV_TDR_STATUS 65245
  67. #define MDIO_MMD_PCS_MV_TDR_STATUS_MASK 0x0003
  68. #define MDIO_MMD_PCS_MV_TDR_STATUS_OFF 0x0001
  69. #define MDIO_MMD_PCS_MV_TDR_STATUS_ON 0x0002
  70. #define MDIO_MMD_PCS_MV_TDR_STATUS_DIST_MASK 0xff00
  71. #define MDIO_MMD_PCS_MV_TDR_STATUS_VCT_STAT_MASK 0x00f0
  72. #define MDIO_MMD_PCS_MV_TDR_STATUS_VCT_STAT_SHORT 0x0030
  73. #define MDIO_MMD_PCS_MV_TDR_STATUS_VCT_STAT_OPEN 0x00e0
  74. #define MDIO_MMD_PCS_MV_TDR_STATUS_VCT_STAT_OK 0x0070
  75. #define MDIO_MMD_PCS_MV_TDR_STATUS_VCT_STAT_IN_PROGR 0x0080
  76. #define MDIO_MMD_PCS_MV_TDR_STATUS_VCT_STAT_NOISE 0x0050
  77. #define MDIO_MMD_PCS_MV_TDR_OFF_CUTOFF 65246
  78. struct mv88q2xxx_priv {
  79. bool enable_temp;
  80. };
  81. struct mmd_val {
  82. int devad;
  83. u32 regnum;
  84. u16 val;
  85. };
  86. static const struct mmd_val mv88q222x_revb0_init_seq0[] = {
  87. { MDIO_MMD_PCS, 0x8033, 0x6801 },
  88. { MDIO_MMD_AN, MDIO_AN_T1_CTRL, 0x0 },
  89. { MDIO_MMD_PMAPMD, MDIO_CTRL1,
  90. MDIO_CTRL1_LPOWER | MDIO_PMA_CTRL1_SPEED1000 },
  91. { MDIO_MMD_PCS, 0xfe1b, 0x48 },
  92. { MDIO_MMD_PCS, 0xffe4, 0x6b6 },
  93. { MDIO_MMD_PMAPMD, MDIO_CTRL1, 0x0 },
  94. { MDIO_MMD_PCS, MDIO_CTRL1, 0x0 },
  95. };
  96. static const struct mmd_val mv88q222x_revb0_init_seq1[] = {
  97. { MDIO_MMD_PCS, 0xfe79, 0x0 },
  98. { MDIO_MMD_PCS, 0xfe07, 0x125a },
  99. { MDIO_MMD_PCS, 0xfe09, 0x1288 },
  100. { MDIO_MMD_PCS, 0xfe08, 0x2588 },
  101. { MDIO_MMD_PCS, 0xfe11, 0x1105 },
  102. { MDIO_MMD_PCS, 0xfe72, 0x042c },
  103. { MDIO_MMD_PCS, 0xfbba, 0xcb2 },
  104. { MDIO_MMD_PCS, 0xfbbb, 0xc4a },
  105. { MDIO_MMD_AN, 0x8032, 0x2020 },
  106. { MDIO_MMD_AN, 0x8031, 0xa28 },
  107. { MDIO_MMD_AN, 0x8031, 0xc28 },
  108. { MDIO_MMD_PCS, 0xffdb, 0xfc10 },
  109. { MDIO_MMD_PCS, 0xfe1b, 0x58 },
  110. { MDIO_MMD_PCS, 0xfe79, 0x4 },
  111. { MDIO_MMD_PCS, 0xfe5f, 0xe8 },
  112. { MDIO_MMD_PCS, 0xfe05, 0x755c },
  113. };
  114. static const struct mmd_val mv88q222x_revb1_init_seq0[] = {
  115. { MDIO_MMD_PCS, 0xffe4, 0x0007 },
  116. { MDIO_MMD_AN, MDIO_AN_T1_CTRL, 0x0 },
  117. { MDIO_MMD_PCS, 0xffe3, 0x7000 },
  118. { MDIO_MMD_PMAPMD, MDIO_CTRL1, 0x0840 },
  119. };
  120. static const struct mmd_val mv88q222x_revb2_init_seq0[] = {
  121. { MDIO_MMD_PCS, 0xffe4, 0x0007 },
  122. { MDIO_MMD_AN, MDIO_AN_T1_CTRL, 0x0 },
  123. { MDIO_MMD_PMAPMD, MDIO_CTRL1, 0x0840 },
  124. };
  125. static const struct mmd_val mv88q222x_revb1_revb2_init_seq1[] = {
  126. { MDIO_MMD_PCS, 0xfe07, 0x125a },
  127. { MDIO_MMD_PCS, 0xfe09, 0x1288 },
  128. { MDIO_MMD_PCS, 0xfe08, 0x2588 },
  129. { MDIO_MMD_PCS, 0xfe72, 0x042c },
  130. { MDIO_MMD_PCS, 0xffe4, 0x0071 },
  131. { MDIO_MMD_PCS, 0xffe4, 0x0001 },
  132. { MDIO_MMD_PCS, 0xfe1b, 0x0048 },
  133. { MDIO_MMD_PMAPMD, 0x0000, 0x0000 },
  134. { MDIO_MMD_PCS, 0x0000, 0x0000 },
  135. { MDIO_MMD_PCS, 0xffdb, 0xfc10 },
  136. { MDIO_MMD_PCS, 0xfe1b, 0x58 },
  137. { MDIO_MMD_PCS, 0xfcad, 0x030c },
  138. { MDIO_MMD_PCS, 0x8032, 0x6001 },
  139. { MDIO_MMD_PCS, 0xfdff, 0x05a5 },
  140. { MDIO_MMD_PCS, 0xfdec, 0xdbaf },
  141. { MDIO_MMD_PCS, 0xfcab, 0x1054 },
  142. { MDIO_MMD_PCS, 0xfcac, 0x1483 },
  143. { MDIO_MMD_PCS, 0x8033, 0xc801 },
  144. { MDIO_MMD_AN, 0x8032, 0x2020 },
  145. { MDIO_MMD_AN, 0x8031, 0xa28 },
  146. { MDIO_MMD_AN, 0x8031, 0xc28 },
  147. { MDIO_MMD_PCS, 0xfbba, 0x0cb2 },
  148. { MDIO_MMD_PCS, 0xfbbb, 0x0c4a },
  149. { MDIO_MMD_PCS, 0xfe5f, 0xe8 },
  150. { MDIO_MMD_PCS, 0xfe05, 0x755c },
  151. { MDIO_MMD_PCS, 0xfa20, 0x002a },
  152. { MDIO_MMD_PCS, 0xfe11, 0x1105 },
  153. };
  154. static int mv88q2xxx_soft_reset(struct phy_device *phydev)
  155. {
  156. int ret;
  157. int val;
  158. ret = phy_write_mmd(phydev, MDIO_MMD_PCS,
  159. MDIO_PCS_1000BT1_CTRL, MDIO_PCS_1000BT1_CTRL_RESET);
  160. if (ret < 0)
  161. return ret;
  162. return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_PCS,
  163. MDIO_PCS_1000BT1_CTRL, val,
  164. !(val & MDIO_PCS_1000BT1_CTRL_RESET),
  165. 50000, 600000, true);
  166. }
  167. static int mv88q2xxx_read_link_gbit(struct phy_device *phydev)
  168. {
  169. int ret;
  170. bool link = false;
  171. /* Read vendor specific Auto-Negotiation status register to get local
  172. * and remote receiver status according to software initialization
  173. * guide. However, when not in polling mode the local and remote
  174. * receiver status are not evaluated due to the Marvell 88Q2xxx APIs.
  175. */
  176. ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_MMD_AN_MV_STAT);
  177. if (ret < 0) {
  178. return ret;
  179. } else if (((ret & MDIO_MMD_AN_MV_STAT_LOCAL_RX) &&
  180. (ret & MDIO_MMD_AN_MV_STAT_REMOTE_RX)) ||
  181. !phy_polling_mode(phydev)) {
  182. /* The link state is latched low so that momentary link
  183. * drops can be detected. Do not double-read the status
  184. * in polling mode to detect such short link drops except
  185. * the link was already down.
  186. */
  187. if (!phy_polling_mode(phydev) || !phydev->link) {
  188. ret = phy_read_mmd(phydev, MDIO_MMD_PCS,
  189. MDIO_PCS_1000BT1_STAT);
  190. if (ret < 0)
  191. return ret;
  192. else if (ret & MDIO_PCS_1000BT1_STAT_LINK)
  193. link = true;
  194. }
  195. if (!link) {
  196. ret = phy_read_mmd(phydev, MDIO_MMD_PCS,
  197. MDIO_PCS_1000BT1_STAT);
  198. if (ret < 0)
  199. return ret;
  200. else if (ret & MDIO_PCS_1000BT1_STAT_LINK)
  201. link = true;
  202. }
  203. }
  204. phydev->link = link;
  205. return 0;
  206. }
  207. static int mv88q2xxx_read_link_100m(struct phy_device *phydev)
  208. {
  209. int ret;
  210. /* The link state is latched low so that momentary link
  211. * drops can be detected. Do not double-read the status
  212. * in polling mode to detect such short link drops except
  213. * the link was already down. In case we are not polling,
  214. * we always read the realtime status.
  215. */
  216. if (!phy_polling_mode(phydev)) {
  217. phydev->link = false;
  218. ret = phy_read_mmd(phydev, MDIO_MMD_PCS,
  219. MDIO_MMD_PCS_MV_100BT1_STAT2);
  220. if (ret < 0)
  221. return ret;
  222. if (ret & MDIO_MMD_PCS_MV_100BT1_STAT2_LINK)
  223. phydev->link = true;
  224. return 0;
  225. } else if (!phydev->link) {
  226. ret = phy_read_mmd(phydev, MDIO_MMD_PCS,
  227. MDIO_MMD_PCS_MV_100BT1_STAT1);
  228. if (ret < 0)
  229. return ret;
  230. else if (ret & MDIO_MMD_PCS_MV_100BT1_STAT1_LINK)
  231. goto out;
  232. }
  233. ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_MMD_PCS_MV_100BT1_STAT1);
  234. if (ret < 0)
  235. return ret;
  236. out:
  237. /* Check if we have link and if the remote and local receiver are ok */
  238. if ((ret & MDIO_MMD_PCS_MV_100BT1_STAT1_LINK) &&
  239. (ret & MDIO_MMD_PCS_MV_100BT1_STAT1_LOCAL_RX) &&
  240. (ret & MDIO_MMD_PCS_MV_100BT1_STAT1_REMOTE_RX))
  241. phydev->link = true;
  242. else
  243. phydev->link = false;
  244. return 0;
  245. }
  246. static int mv88q2xxx_read_link(struct phy_device *phydev)
  247. {
  248. /* The 88Q2XXX PHYs do not have the PMA/PMD status register available,
  249. * therefore we need to read the link status from the vendor specific
  250. * registers depending on the speed.
  251. */
  252. if (phydev->speed == SPEED_1000)
  253. return mv88q2xxx_read_link_gbit(phydev);
  254. else if (phydev->speed == SPEED_100)
  255. return mv88q2xxx_read_link_100m(phydev);
  256. phydev->link = false;
  257. return 0;
  258. }
  259. static int mv88q2xxx_read_master_slave_state(struct phy_device *phydev)
  260. {
  261. int ret;
  262. phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN;
  263. ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_MMD_AN_MV_STAT);
  264. if (ret < 0)
  265. return ret;
  266. if (ret & MDIO_MMD_AN_MV_STAT_LOCAL_MASTER)
  267. phydev->master_slave_state = MASTER_SLAVE_STATE_MASTER;
  268. else
  269. phydev->master_slave_state = MASTER_SLAVE_STATE_SLAVE;
  270. return 0;
  271. }
  272. static int mv88q2xxx_read_aneg_speed(struct phy_device *phydev)
  273. {
  274. int ret;
  275. phydev->speed = SPEED_UNKNOWN;
  276. ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_MMD_AN_MV_STAT2);
  277. if (ret < 0)
  278. return ret;
  279. if (!(ret & MDIO_MMD_AN_MV_STAT2_AN_RESOLVED))
  280. return 0;
  281. if (ret & MDIO_MMD_AN_MV_STAT2_100BT1)
  282. phydev->speed = SPEED_100;
  283. else if (ret & MDIO_MMD_AN_MV_STAT2_1000BT1)
  284. phydev->speed = SPEED_1000;
  285. return 0;
  286. }
  287. static int mv88q2xxx_read_status(struct phy_device *phydev)
  288. {
  289. int ret;
  290. if (phydev->autoneg == AUTONEG_ENABLE) {
  291. /* We have to get the negotiated speed first, otherwise we are
  292. * not able to read the link.
  293. */
  294. ret = mv88q2xxx_read_aneg_speed(phydev);
  295. if (ret < 0)
  296. return ret;
  297. ret = mv88q2xxx_read_link(phydev);
  298. if (ret < 0)
  299. return ret;
  300. ret = genphy_c45_read_lpa(phydev);
  301. if (ret < 0)
  302. return ret;
  303. ret = genphy_c45_baset1_read_status(phydev);
  304. if (ret < 0)
  305. return ret;
  306. ret = mv88q2xxx_read_master_slave_state(phydev);
  307. if (ret < 0)
  308. return ret;
  309. phy_resolve_aneg_linkmode(phydev);
  310. return 0;
  311. }
  312. ret = mv88q2xxx_read_link(phydev);
  313. if (ret < 0)
  314. return ret;
  315. return genphy_c45_read_pma(phydev);
  316. }
  317. static int mv88q2xxx_get_features(struct phy_device *phydev)
  318. {
  319. int ret;
  320. ret = genphy_c45_pma_read_abilities(phydev);
  321. if (ret)
  322. return ret;
  323. /* We need to read the baset1 extended abilities manually because the
  324. * PHY does not signalize it has the extended abilities register
  325. * available.
  326. */
  327. ret = genphy_c45_pma_baset1_read_abilities(phydev);
  328. if (ret)
  329. return ret;
  330. /* The PHY signalizes it supports autonegotiation. Unfortunately, so
  331. * far it was not possible to get a link even when following the init
  332. * sequence provided by Marvell. Disable it for now until a proper
  333. * workaround is found or a new PHY revision is released.
  334. */
  335. if (phydev->drv->phy_id == MARVELL_PHY_ID_88Q2110)
  336. linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
  337. phydev->supported);
  338. return 0;
  339. }
  340. static int mv88q2xxx_config_aneg(struct phy_device *phydev)
  341. {
  342. int ret;
  343. ret = genphy_c45_config_aneg(phydev);
  344. if (ret)
  345. return ret;
  346. return phydev->drv->soft_reset(phydev);
  347. }
  348. static int mv88q2xxx_config_init(struct phy_device *phydev)
  349. {
  350. /* The 88Q2XXX PHYs do have the extended ability register available, but
  351. * register MDIO_PMA_EXTABLE where they should signalize it does not
  352. * work according to specification. Therefore, we force it here.
  353. */
  354. phydev->pma_extable = MDIO_PMA_EXTABLE_BT1;
  355. /* Configure interrupt with default settings, output is driven low for
  356. * active interrupt and high for inactive.
  357. */
  358. if (phy_interrupt_is_valid(phydev))
  359. return phy_set_bits_mmd(phydev, MDIO_MMD_PCS,
  360. MDIO_MMD_PCS_MV_GPIO_INT_CTRL,
  361. MDIO_MMD_PCS_MV_GPIO_INT_CTRL_TRI_DIS);
  362. return 0;
  363. }
  364. static int mv88q2xxx_get_sqi(struct phy_device *phydev)
  365. {
  366. int ret;
  367. if (phydev->speed == SPEED_100) {
  368. /* Read the SQI from the vendor specific receiver status
  369. * register
  370. */
  371. ret = phy_read_mmd(phydev, MDIO_MMD_PCS,
  372. MDIO_MMD_PCS_MV_RX_STAT);
  373. if (ret < 0)
  374. return ret;
  375. ret = ret >> 12;
  376. } else {
  377. /* Read from vendor specific registers, they are not documented
  378. * but can be found in the Software Initialization Guide. Only
  379. * revisions >= A0 are supported.
  380. */
  381. ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, 0xfc5d, 0xff, 0xac);
  382. if (ret < 0)
  383. return ret;
  384. ret = phy_read_mmd(phydev, MDIO_MMD_PCS, 0xfc88);
  385. if (ret < 0)
  386. return ret;
  387. }
  388. return ret & 0x0f;
  389. }
  390. static int mv88q2xxx_get_sqi_max(struct phy_device *phydev)
  391. {
  392. return 15;
  393. }
  394. static int mv88q2xxx_config_intr(struct phy_device *phydev)
  395. {
  396. int ret;
  397. if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
  398. /* Enable interrupts for 1000BASE-T1 link up and down events
  399. * and enable general interrupts for 100BASE-T1.
  400. */
  401. ret = phy_write_mmd(phydev, MDIO_MMD_PCS,
  402. MDIO_MMD_PCS_MV_INT_EN,
  403. MDIO_MMD_PCS_MV_INT_EN_LINK_UP |
  404. MDIO_MMD_PCS_MV_INT_EN_LINK_DOWN |
  405. MDIO_MMD_PCS_MV_INT_EN_100BT1);
  406. if (ret < 0)
  407. return ret;
  408. /* Enable interrupts for 100BASE-T1 link events */
  409. return phy_write_mmd(phydev, MDIO_MMD_PCS,
  410. MDIO_MMD_PCS_MV_100BT1_INT_EN,
  411. MDIO_MMD_PCS_MV_100BT1_INT_EN_LINKEVENT);
  412. } else {
  413. ret = phy_write_mmd(phydev, MDIO_MMD_PCS,
  414. MDIO_MMD_PCS_MV_INT_EN, 0);
  415. if (ret < 0)
  416. return ret;
  417. return phy_write_mmd(phydev, MDIO_MMD_PCS,
  418. MDIO_MMD_PCS_MV_100BT1_INT_EN, 0);
  419. }
  420. }
  421. static irqreturn_t mv88q2xxx_handle_interrupt(struct phy_device *phydev)
  422. {
  423. bool trigger_machine = false;
  424. int irq;
  425. /* Before we can acknowledge the 100BT1 general interrupt, that is in
  426. * the 1000BT1 interrupt status register, we have to acknowledge any
  427. * interrupts that are related to it. Therefore we read first the 100BT1
  428. * interrupt status register, followed by reading the 1000BT1 interrupt
  429. * status register.
  430. */
  431. irq = phy_read_mmd(phydev, MDIO_MMD_PCS,
  432. MDIO_MMD_PCS_MV_COPPER_INT_STAT);
  433. if (irq < 0) {
  434. phy_error(phydev);
  435. return IRQ_NONE;
  436. }
  437. /* Check link status for 100BT1 */
  438. if (irq & MDIO_MMD_PCS_MV_COPPER_INT_STAT_LINKEVENT)
  439. trigger_machine = true;
  440. irq = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_MMD_PCS_MV_GPIO_INT_STAT);
  441. if (irq < 0) {
  442. phy_error(phydev);
  443. return IRQ_NONE;
  444. }
  445. /* Check link status for 1000BT1 */
  446. if ((irq & MDIO_MMD_PCS_MV_GPIO_INT_STAT_LINK_UP) ||
  447. (irq & MDIO_MMD_PCS_MV_GPIO_INT_STAT_LINK_DOWN))
  448. trigger_machine = true;
  449. if (!trigger_machine)
  450. return IRQ_NONE;
  451. phy_trigger_machine(phydev);
  452. return IRQ_HANDLED;
  453. }
  454. static int mv88q2xxx_suspend(struct phy_device *phydev)
  455. {
  456. int ret;
  457. /* Disable PHY interrupts */
  458. if (phy_interrupt_is_valid(phydev)) {
  459. phydev->interrupts = PHY_INTERRUPT_DISABLED;
  460. ret = mv88q2xxx_config_intr(phydev);
  461. if (ret)
  462. return ret;
  463. }
  464. return phy_set_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1,
  465. MDIO_CTRL1_LPOWER);
  466. }
  467. static int mv88q2xxx_resume(struct phy_device *phydev)
  468. {
  469. int ret;
  470. /* Enable PHY interrupts */
  471. if (phy_interrupt_is_valid(phydev)) {
  472. phydev->interrupts = PHY_INTERRUPT_ENABLED;
  473. ret = mv88q2xxx_config_intr(phydev);
  474. if (ret)
  475. return ret;
  476. }
  477. return phy_clear_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1,
  478. MDIO_CTRL1_LPOWER);
  479. }
  480. #if IS_ENABLED(CONFIG_HWMON)
  481. static const struct hwmon_channel_info * const mv88q2xxx_hwmon_info[] = {
  482. HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_ALARM),
  483. NULL
  484. };
  485. static umode_t mv88q2xxx_hwmon_is_visible(const void *data,
  486. enum hwmon_sensor_types type,
  487. u32 attr, int channel)
  488. {
  489. switch (attr) {
  490. case hwmon_temp_input:
  491. return 0444;
  492. case hwmon_temp_max:
  493. return 0644;
  494. case hwmon_temp_alarm:
  495. return 0444;
  496. default:
  497. return 0;
  498. }
  499. }
  500. static int mv88q2xxx_hwmon_read(struct device *dev,
  501. enum hwmon_sensor_types type,
  502. u32 attr, int channel, long *val)
  503. {
  504. struct phy_device *phydev = dev_get_drvdata(dev);
  505. int ret;
  506. switch (attr) {
  507. case hwmon_temp_input:
  508. ret = phy_read_mmd(phydev, MDIO_MMD_PCS,
  509. MDIO_MMD_PCS_MV_TEMP_SENSOR3);
  510. if (ret < 0)
  511. return ret;
  512. ret = FIELD_GET(MDIO_MMD_PCS_MV_TEMP_SENSOR3_MASK, ret);
  513. *val = (ret - 75) * 1000;
  514. return 0;
  515. case hwmon_temp_max:
  516. ret = phy_read_mmd(phydev, MDIO_MMD_PCS,
  517. MDIO_MMD_PCS_MV_TEMP_SENSOR3);
  518. if (ret < 0)
  519. return ret;
  520. ret = FIELD_GET(MDIO_MMD_PCS_MV_TEMP_SENSOR3_INT_THRESH_MASK,
  521. ret);
  522. *val = (ret - 75) * 1000;
  523. return 0;
  524. case hwmon_temp_alarm:
  525. ret = phy_read_mmd(phydev, MDIO_MMD_PCS,
  526. MDIO_MMD_PCS_MV_TEMP_SENSOR1);
  527. if (ret < 0)
  528. return ret;
  529. *val = !!(ret & MDIO_MMD_PCS_MV_TEMP_SENSOR1_RAW_INT);
  530. return 0;
  531. default:
  532. return -EOPNOTSUPP;
  533. }
  534. }
  535. static int mv88q2xxx_hwmon_write(struct device *dev,
  536. enum hwmon_sensor_types type, u32 attr,
  537. int channel, long val)
  538. {
  539. struct phy_device *phydev = dev_get_drvdata(dev);
  540. switch (attr) {
  541. case hwmon_temp_max:
  542. clamp_val(val, -75000, 180000);
  543. val = (val / 1000) + 75;
  544. val = FIELD_PREP(MDIO_MMD_PCS_MV_TEMP_SENSOR3_INT_THRESH_MASK,
  545. val);
  546. return phy_modify_mmd(phydev, MDIO_MMD_PCS,
  547. MDIO_MMD_PCS_MV_TEMP_SENSOR3,
  548. MDIO_MMD_PCS_MV_TEMP_SENSOR3_INT_THRESH_MASK,
  549. val);
  550. default:
  551. return -EOPNOTSUPP;
  552. }
  553. }
  554. static const struct hwmon_ops mv88q2xxx_hwmon_hwmon_ops = {
  555. .is_visible = mv88q2xxx_hwmon_is_visible,
  556. .read = mv88q2xxx_hwmon_read,
  557. .write = mv88q2xxx_hwmon_write,
  558. };
  559. static const struct hwmon_chip_info mv88q2xxx_hwmon_chip_info = {
  560. .ops = &mv88q2xxx_hwmon_hwmon_ops,
  561. .info = mv88q2xxx_hwmon_info,
  562. };
  563. static int mv88q2xxx_hwmon_probe(struct phy_device *phydev)
  564. {
  565. struct mv88q2xxx_priv *priv = phydev->priv;
  566. struct device *dev = &phydev->mdio.dev;
  567. struct device *hwmon;
  568. char *hwmon_name;
  569. priv->enable_temp = true;
  570. hwmon_name = devm_hwmon_sanitize_name(dev, dev_name(dev));
  571. if (IS_ERR(hwmon_name))
  572. return PTR_ERR(hwmon_name);
  573. hwmon = devm_hwmon_device_register_with_info(dev,
  574. hwmon_name,
  575. phydev,
  576. &mv88q2xxx_hwmon_chip_info,
  577. NULL);
  578. return PTR_ERR_OR_ZERO(hwmon);
  579. }
  580. #else
  581. static int mv88q2xxx_hwmon_probe(struct phy_device *phydev)
  582. {
  583. return 0;
  584. }
  585. #endif
  586. static int mv88q2xxx_probe(struct phy_device *phydev)
  587. {
  588. struct mv88q2xxx_priv *priv;
  589. priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
  590. if (!priv)
  591. return -ENOMEM;
  592. phydev->priv = priv;
  593. return mv88q2xxx_hwmon_probe(phydev);
  594. }
  595. static int mv88q222x_soft_reset(struct phy_device *phydev)
  596. {
  597. int ret;
  598. /* Enable RESET of DCL */
  599. if (phydev->autoneg == AUTONEG_ENABLE || phydev->speed == SPEED_1000) {
  600. ret = phy_write_mmd(phydev, MDIO_MMD_PCS, 0xfe1b, 0x48);
  601. if (ret < 0)
  602. return ret;
  603. }
  604. ret = phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_1000BT1_CTRL,
  605. MDIO_PCS_1000BT1_CTRL_RESET);
  606. if (ret < 0)
  607. return ret;
  608. ret = phy_write_mmd(phydev, MDIO_MMD_PCS, 0xffe4, 0xc);
  609. if (ret < 0)
  610. return ret;
  611. /* Disable RESET of DCL */
  612. if (phydev->autoneg == AUTONEG_ENABLE || phydev->speed == SPEED_1000)
  613. return phy_write_mmd(phydev, MDIO_MMD_PCS, 0xfe1b, 0x58);
  614. return 0;
  615. }
  616. static int mv88q222x_write_mmd_vals(struct phy_device *phydev,
  617. const struct mmd_val *vals, size_t len)
  618. {
  619. int ret;
  620. for (; len; vals++, len--) {
  621. ret = phy_write_mmd(phydev, vals->devad, vals->regnum,
  622. vals->val);
  623. if (ret < 0)
  624. return ret;
  625. }
  626. return 0;
  627. }
  628. static int mv88q222x_revb0_config_init(struct phy_device *phydev)
  629. {
  630. int ret;
  631. ret = mv88q222x_write_mmd_vals(phydev, mv88q222x_revb0_init_seq0,
  632. ARRAY_SIZE(mv88q222x_revb0_init_seq0));
  633. if (ret < 0)
  634. return ret;
  635. usleep_range(5000, 10000);
  636. ret = mv88q222x_write_mmd_vals(phydev, mv88q222x_revb0_init_seq1,
  637. ARRAY_SIZE(mv88q222x_revb0_init_seq1));
  638. if (ret < 0)
  639. return ret;
  640. return mv88q2xxx_config_init(phydev);
  641. }
  642. static int mv88q222x_revb1_revb2_config_init(struct phy_device *phydev)
  643. {
  644. bool is_rev_b1 = phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] == PHY_ID_88Q2220_REVB1;
  645. int ret;
  646. if (is_rev_b1)
  647. ret = mv88q222x_write_mmd_vals(phydev, mv88q222x_revb1_init_seq0,
  648. ARRAY_SIZE(mv88q222x_revb1_init_seq0));
  649. else
  650. ret = mv88q222x_write_mmd_vals(phydev, mv88q222x_revb2_init_seq0,
  651. ARRAY_SIZE(mv88q222x_revb2_init_seq0));
  652. if (ret < 0)
  653. return ret;
  654. usleep_range(3000, 5000);
  655. ret = mv88q222x_write_mmd_vals(phydev, mv88q222x_revb1_revb2_init_seq1,
  656. ARRAY_SIZE(mv88q222x_revb1_revb2_init_seq1));
  657. if (ret < 0)
  658. return ret;
  659. return mv88q2xxx_config_init(phydev);
  660. }
  661. static int mv88q222x_config_init(struct phy_device *phydev)
  662. {
  663. struct mv88q2xxx_priv *priv = phydev->priv;
  664. int ret;
  665. /* Enable temperature sense */
  666. if (priv->enable_temp) {
  667. ret = phy_modify_mmd(phydev, MDIO_MMD_PCS,
  668. MDIO_MMD_PCS_MV_TEMP_SENSOR2,
  669. MDIO_MMD_PCS_MV_TEMP_SENSOR2_DIS_MASK, 0);
  670. if (ret < 0)
  671. return ret;
  672. }
  673. if (phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] == PHY_ID_88Q2220_REVB0)
  674. return mv88q222x_revb0_config_init(phydev);
  675. else
  676. return mv88q222x_revb1_revb2_config_init(phydev);
  677. }
  678. static int mv88q222x_cable_test_start(struct phy_device *phydev)
  679. {
  680. int ret;
  681. ret = phy_write_mmd(phydev, MDIO_MMD_PCS,
  682. MDIO_MMD_PCS_MV_TDR_OFF_CUTOFF, 0x0058);
  683. if (ret < 0)
  684. return ret;
  685. ret = phy_write_mmd(phydev, MDIO_MMD_PCS,
  686. MDIO_MMD_PCS_MV_TDR_OFF_LONG_CABLE, 0x00eb);
  687. if (ret < 0)
  688. return ret;
  689. ret = phy_write_mmd(phydev, MDIO_MMD_PCS,
  690. MDIO_MMD_PCS_MV_TDR_OFF_SHORT_CABLE, 0x010e);
  691. if (ret < 0)
  692. return ret;
  693. ret = phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_MMD_PCS_MV_TDR_RESET,
  694. 0x0d90);
  695. if (ret < 0)
  696. return ret;
  697. ret = phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_MMD_PCS_MV_TDR_STATUS,
  698. MDIO_MMD_PCS_MV_TDR_STATUS_ON);
  699. if (ret < 0)
  700. return ret;
  701. /* According to the Marvell API the test is finished within 500 ms */
  702. msleep(500);
  703. return 0;
  704. }
  705. static int mv88q222x_cable_test_get_status(struct phy_device *phydev,
  706. bool *finished)
  707. {
  708. int ret, status;
  709. u32 dist;
  710. status = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_MMD_PCS_MV_TDR_STATUS);
  711. if (status < 0)
  712. return status;
  713. ret = phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_MMD_PCS_MV_TDR_RESET,
  714. MDIO_MMD_PCS_MV_TDR_RESET_TDR_RST | 0xd90);
  715. if (ret < 0)
  716. return ret;
  717. /* Test could not be finished */
  718. if (FIELD_GET(MDIO_MMD_PCS_MV_TDR_STATUS_MASK, status) !=
  719. MDIO_MMD_PCS_MV_TDR_STATUS_OFF)
  720. return -ETIMEDOUT;
  721. *finished = true;
  722. /* Fault length reported in meters, convert to centimeters */
  723. dist = FIELD_GET(MDIO_MMD_PCS_MV_TDR_STATUS_DIST_MASK, status) * 100;
  724. switch (status & MDIO_MMD_PCS_MV_TDR_STATUS_VCT_STAT_MASK) {
  725. case MDIO_MMD_PCS_MV_TDR_STATUS_VCT_STAT_OPEN:
  726. ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A,
  727. ETHTOOL_A_CABLE_RESULT_CODE_OPEN);
  728. ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_A,
  729. dist);
  730. break;
  731. case MDIO_MMD_PCS_MV_TDR_STATUS_VCT_STAT_SHORT:
  732. ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A,
  733. ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT);
  734. ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_A,
  735. dist);
  736. break;
  737. case MDIO_MMD_PCS_MV_TDR_STATUS_VCT_STAT_OK:
  738. ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A,
  739. ETHTOOL_A_CABLE_RESULT_CODE_OK);
  740. break;
  741. default:
  742. ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A,
  743. ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC);
  744. }
  745. return 0;
  746. }
  747. static struct phy_driver mv88q2xxx_driver[] = {
  748. {
  749. .phy_id = MARVELL_PHY_ID_88Q2110,
  750. .phy_id_mask = MARVELL_PHY_ID_MASK,
  751. .name = "mv88q2110",
  752. .get_features = mv88q2xxx_get_features,
  753. .config_aneg = mv88q2xxx_config_aneg,
  754. .config_init = mv88q2xxx_config_init,
  755. .read_status = mv88q2xxx_read_status,
  756. .soft_reset = mv88q2xxx_soft_reset,
  757. .set_loopback = genphy_c45_loopback,
  758. .get_sqi = mv88q2xxx_get_sqi,
  759. .get_sqi_max = mv88q2xxx_get_sqi_max,
  760. },
  761. {
  762. .phy_id = MARVELL_PHY_ID_88Q2220,
  763. .phy_id_mask = MARVELL_PHY_ID_MASK,
  764. .name = "mv88q2220",
  765. .flags = PHY_POLL_CABLE_TEST,
  766. .probe = mv88q2xxx_probe,
  767. .get_features = mv88q2xxx_get_features,
  768. .config_aneg = mv88q2xxx_config_aneg,
  769. .aneg_done = genphy_c45_aneg_done,
  770. .config_init = mv88q222x_config_init,
  771. .read_status = mv88q2xxx_read_status,
  772. .soft_reset = mv88q222x_soft_reset,
  773. .config_intr = mv88q2xxx_config_intr,
  774. .handle_interrupt = mv88q2xxx_handle_interrupt,
  775. .set_loopback = genphy_c45_loopback,
  776. .cable_test_start = mv88q222x_cable_test_start,
  777. .cable_test_get_status = mv88q222x_cable_test_get_status,
  778. .get_sqi = mv88q2xxx_get_sqi,
  779. .get_sqi_max = mv88q2xxx_get_sqi_max,
  780. .suspend = mv88q2xxx_suspend,
  781. .resume = mv88q2xxx_resume,
  782. },
  783. };
  784. module_phy_driver(mv88q2xxx_driver);
  785. static struct mdio_device_id __maybe_unused mv88q2xxx_tbl[] = {
  786. { MARVELL_PHY_ID_88Q2110, MARVELL_PHY_ID_MASK },
  787. { MARVELL_PHY_ID_88Q2220, MARVELL_PHY_ID_MASK },
  788. { /*sentinel*/ }
  789. };
  790. MODULE_DEVICE_TABLE(mdio, mv88q2xxx_tbl);
  791. MODULE_DESCRIPTION("Marvell 88Q2XXX 100/1000BASE-T1 Automotive Ethernet PHY driver");
  792. MODULE_LICENSE("GPL");