mscc.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083
  1. // SPDX-License-Identifier: MIT
  2. /*
  3. * Microsemi PHY drivers
  4. *
  5. *
  6. * Copyright (c) 2016 Microsemi Corporation
  7. *
  8. * Author: John Haechten
  9. *
  10. */
  11. #include <miiphy.h>
  12. #include <bitfield.h>
  13. #include <time.h>
  14. #include <linux/delay.h>
  15. /* Microsemi PHY ID's */
  16. #define PHY_ID_VSC8530 0x00070560
  17. #define PHY_ID_VSC8531 0x00070570
  18. #define PHY_ID_VSC8540 0x00070760
  19. #define PHY_ID_VSC8541 0x00070770
  20. #define PHY_ID_VSC8584 0x000707c0
  21. /* Microsemi VSC85xx PHY Register Pages */
  22. #define MSCC_EXT_PAGE_ACCESS 31 /* Page Access Register */
  23. #define MSCC_PHY_PAGE_STD 0x0000 /* Standard registers */
  24. #define MSCC_PHY_PAGE_EXT1 0x0001 /* Extended registers - page 1 */
  25. #define MSCC_PHY_PAGE_EXT2 0x0002 /* Extended registers - page 2 */
  26. #define MSCC_PHY_PAGE_EXT3 0x0003 /* Extended registers - page 3 */
  27. #define MSCC_PHY_PAGE_EXT4 0x0004 /* Extended registers - page 4 */
  28. #define MSCC_PHY_PAGE_GPIO 0x0010 /* GPIO registers */
  29. #define MSCC_PHY_PAGE_TEST 0x2A30 /* TEST Page registers */
  30. #define MSCC_PHY_PAGE_TR 0x52B5 /* Token Ring Page registers */
  31. /* Std Page Register 18 */
  32. #define MSCC_PHY_BYPASS_CONTROL 18
  33. #define PARALLEL_DET_IGNORE_ADVERTISED BIT(3)
  34. /* Std Page Register 22 */
  35. #define MSCC_PHY_EXT_CNTL_STATUS 22
  36. #define SMI_BROADCAST_WR_EN BIT(0)
  37. /* Std Page Register 28 - PHY AUX Control/Status */
  38. #define MIIM_AUX_CNTRL_STAT_REG 28
  39. #define MIIM_AUX_CNTRL_STAT_ACTIPHY_TO (0x0004)
  40. #define MIIM_AUX_CNTRL_STAT_F_DUPLEX (0x0020)
  41. #define MIIM_AUX_CNTRL_STAT_SPEED_MASK (0x0018)
  42. #define MIIM_AUX_CNTRL_STAT_SPEED_POS (3)
  43. #define MIIM_AUX_CNTRL_STAT_SPEED_10M (0x0)
  44. #define MIIM_AUX_CNTRL_STAT_SPEED_100M (0x1)
  45. #define MIIM_AUX_CNTRL_STAT_SPEED_1000M (0x2)
  46. /* Std Page Register 23 - Extended PHY CTRL_1 */
  47. #define MSCC_PHY_EXT_PHY_CNTL_1_REG 23
  48. #define MAC_IF_SELECTION_MASK (0x1800)
  49. #define MAC_IF_SELECTION_GMII (0)
  50. #define MAC_IF_SELECTION_RMII (1)
  51. #define MAC_IF_SELECTION_RGMII (2)
  52. #define MAC_IF_SELECTION_POS (11)
  53. #define MAC_IF_SELECTION_WIDTH (2)
  54. #define VSC8584_MAC_IF_SELECTION_MASK BIT(12)
  55. #define VSC8584_MAC_IF_SELECTION_SGMII 0
  56. #define VSC8584_MAC_IF_SELECTION_1000BASEX 1
  57. #define VSC8584_MAC_IF_SELECTION_POS 12
  58. #define MEDIA_OP_MODE_MASK GENMASK(10, 8)
  59. #define MEDIA_OP_MODE_COPPER 0
  60. #define MEDIA_OP_MODE_SERDES 1
  61. #define MEDIA_OP_MODE_1000BASEX 2
  62. #define MEDIA_OP_MODE_100BASEFX 3
  63. #define MEDIA_OP_MODE_AMS_COPPER_SERDES 5
  64. #define MEDIA_OP_MODE_AMS_COPPER_1000BASEX 6
  65. #define MEDIA_OP_MODE_AMS_COPPER_100BASEFX 7
  66. #define MEDIA_OP_MODE_POS 8
  67. /* Extended Page 1 Register 20E1 */
  68. #define MSCC_PHY_ACTIPHY_CNTL 20
  69. #define PHY_ADDR_REVERSED BIT(9)
  70. /* Extended Page 1 Register 23E1 */
  71. #define MSCC_PHY_EXT_PHY_CNTL_4 23
  72. #define PHY_CNTL_4_ADDR_POS 11
  73. /* Extended Page 1 Register 25E1 */
  74. #define MSCC_PHY_VERIPHY_CNTL_2 25
  75. /* Extended Page 1 Register 26E1 */
  76. #define MSCC_PHY_VERIPHY_CNTL_3 26
  77. /* Extended Page 2 Register 16E2 */
  78. #define MSCC_PHY_CU_PMD_TX_CNTL 16
  79. /* Extended Page 2 Register 20E2 */
  80. #define MSCC_PHY_RGMII_CNTL_REG 20
  81. #define VSC_FAST_LINK_FAIL2_ENA_MASK (0x8000)
  82. #define RX_CLK_OUT_MASK (0x0800)
  83. #define RX_CLK_OUT_POS (11)
  84. #define RX_CLK_OUT_WIDTH (1)
  85. #define RX_CLK_OUT_NORMAL (0)
  86. #define RX_CLK_OUT_DISABLE (1)
  87. #define RGMII_RX_CLK_DELAY_POS (4)
  88. #define RGMII_RX_CLK_DELAY_WIDTH (3)
  89. #define RGMII_RX_CLK_DELAY_MASK (0x0070)
  90. #define RGMII_TX_CLK_DELAY_POS (0)
  91. #define RGMII_TX_CLK_DELAY_WIDTH (3)
  92. #define RGMII_TX_CLK_DELAY_MASK (0x0007)
  93. /* Extended Page 2 Register 27E2 */
  94. #define MSCC_PHY_WOL_MAC_CONTROL 27
  95. #define EDGE_RATE_CNTL_POS (5)
  96. #define EDGE_RATE_CNTL_WIDTH (3)
  97. #define EDGE_RATE_CNTL_MASK (0x00E0)
  98. #define RMII_CLK_OUT_ENABLE_POS (4)
  99. #define RMII_CLK_OUT_ENABLE_WIDTH (1)
  100. #define RMII_CLK_OUT_ENABLE_MASK (0x10)
  101. /* Extended Page 3 Register 22E3 */
  102. #define MSCC_PHY_SERDES_TX_CRC_ERR_CNT 22
  103. /* Extended page GPIO register 00G */
  104. #define MSCC_DW8051_CNTL_STATUS 0
  105. #define MICRO_NSOFT_RESET BIT(15)
  106. #define RUN_FROM_INT_ROM BIT(14)
  107. #define AUTOINC_ADDR BIT(13)
  108. #define PATCH_RAM_CLK BIT(12)
  109. #define MICRO_PATCH_EN BIT(7)
  110. #define DW8051_CLK_EN BIT(4)
  111. #define MICRO_CLK_EN BIT(3)
  112. #define MICRO_CLK_DIVIDE(x) ((x) >> 1)
  113. /* Extended page GPIO register 09G */
  114. #define MSCC_TRAP_ROM_ADDR(x) ((x) * 2 + 1)
  115. /* Extended page GPIO register 10G */
  116. #define MSCC_PATCH_RAM_ADDR(x) (((x) + 1) * 2)
  117. /* Extended page GPIO register 11G */
  118. #define MSCC_INT_MEM_ADDR 11
  119. /* Extended page GPIO register 12G */
  120. #define MSCC_INT_MEM_CNTL 12
  121. #define READ_SFR (BIT(14) | BIT(13))
  122. #define READ_PRAM BIT(14)
  123. #define READ_ROM BIT(13)
  124. #define READ_RAM (0x00 << 13)
  125. #define INT_MEM_WRITE_EN BIT(12)
  126. #define EN_PATCH_RAM_TRAP_ADDR(x) BIT((x) + 7)
  127. #define INT_MEM_DATA_M GENMASK(7, 0)
  128. #define INT_MEM_DATA(x) (INT_MEM_DATA_M & (x))
  129. /* Extended page GPIO register 18G */
  130. #define MSCC_PHY_PROC_CMD 18
  131. #define PROC_CMD_NCOMPLETED BIT(15)
  132. #define PROC_CMD_FAILED BIT(14)
  133. #define PROC_CMD_SGMII_PORT(x) ((x) << 8)
  134. #define PROC_CMD_FIBER_PORT(x) BIT(8 + (x) % 4)
  135. #define PROC_CMD_QSGMII_PORT (BIT(11) | BIT(10))
  136. #define PROC_CMD_RST_CONF_PORT BIT(7)
  137. #define PROC_CMD_RECONF_PORT (0 << 7)
  138. #define PROC_CMD_READ_MOD_WRITE_PORT BIT(6)
  139. #define PROC_CMD_WRITE BIT(6)
  140. #define PROC_CMD_READ (0 << 6)
  141. #define PROC_CMD_FIBER_DISABLE BIT(5)
  142. #define PROC_CMD_FIBER_100BASE_FX BIT(4)
  143. #define PROC_CMD_FIBER_1000BASE_X (0 << 4)
  144. #define PROC_CMD_SGMII_MAC (BIT(5) | BIT(4))
  145. #define PROC_CMD_QSGMII_MAC BIT(5)
  146. #define PROC_CMD_NO_MAC_CONF (0x00 << 4)
  147. #define PROC_CMD_NOP GENMASK(3, 0)
  148. #define PROC_CMD_CRC16 BIT(3)
  149. #define PROC_CMD_FIBER_MEDIA_CONF BIT(0)
  150. #define PROC_CMD_MCB_ACCESS_MAC_CONF (0x0000 << 0)
  151. #define PROC_CMD_NCOMPLETED_TIMEOUT_MS 500
  152. /* Extended page GPIO register 19G */
  153. #define MSCC_PHY_MAC_CFG_FASTLINK 19
  154. #define MAC_CFG_MASK GENMASK(15, 14)
  155. #define MAC_CFG_SGMII (0x00 << 14)
  156. #define MAC_CFG_QSGMII BIT(14)
  157. /* Test Registers */
  158. #define MSCC_PHY_TEST_PAGE_5 5
  159. #define MSCC_PHY_TEST_PAGE_8 8
  160. #define TR_CLK_DISABLE BIT(15)
  161. /* Token Ring Page 0x52B5 Registers */
  162. #define MSCC_PHY_REG_TR_ADDR_16 16
  163. #define MSCC_PHY_REG_TR_DATA_17 17
  164. #define MSCC_PHY_REG_TR_DATA_18 18
  165. /* Token Ring - Read Value in */
  166. #define MSCC_PHY_TR_16_READ (0xA000)
  167. /* Token Ring - Write Value out */
  168. #define MSCC_PHY_TR_16_WRITE (0x8000)
  169. /* Token Ring Registers */
  170. #define MSCC_PHY_TR_LINKDETCTRL_POS (3)
  171. #define MSCC_PHY_TR_LINKDETCTRL_WIDTH (2)
  172. #define MSCC_PHY_TR_LINKDETCTRL_VAL (3)
  173. #define MSCC_PHY_TR_LINKDETCTRL_MASK (0x0018)
  174. #define MSCC_PHY_TR_LINKDETCTRL_ADDR (0x07F8)
  175. #define MSCC_PHY_TR_VGATHRESH100_POS (0)
  176. #define MSCC_PHY_TR_VGATHRESH100_WIDTH (7)
  177. #define MSCC_PHY_TR_VGATHRESH100_VAL (0x0018)
  178. #define MSCC_PHY_TR_VGATHRESH100_MASK (0x007f)
  179. #define MSCC_PHY_TR_VGATHRESH100_ADDR (0x0FA4)
  180. #define MSCC_PHY_TR_VGAGAIN10_U_POS (0)
  181. #define MSCC_PHY_TR_VGAGAIN10_U_WIDTH (1)
  182. #define MSCC_PHY_TR_VGAGAIN10_U_MASK (0x0001)
  183. #define MSCC_PHY_TR_VGAGAIN10_U_VAL (0)
  184. #define MSCC_PHY_TR_VGAGAIN10_L_POS (12)
  185. #define MSCC_PHY_TR_VGAGAIN10_L_WIDTH (4)
  186. #define MSCC_PHY_TR_VGAGAIN10_L_MASK (0xf000)
  187. #define MSCC_PHY_TR_VGAGAIN10_L_VAL (0x0001)
  188. #define MSCC_PHY_TR_VGAGAIN10_ADDR (0x0F92)
  189. /* General Timeout Values */
  190. #define MSCC_PHY_RESET_TIMEOUT (100)
  191. #define MSCC_PHY_MICRO_TIMEOUT (500)
  192. #define VSC8584_REVB 0x0001
  193. #define MSCC_DEV_REV_MASK GENMASK(3, 0)
  194. #define MSCC_VSC8584_REVB_INT8051_FW_START_ADDR 0xe800
  195. #define MSCC_VSC8584_REVB_INT8051_FW_CRC 0xfb48
  196. /* RGMII/GMII Clock Delay (Skew) Options */ enum vsc_phy_rgmii_skew {
  197. VSC_PHY_RGMII_DELAY_200_PS,
  198. VSC_PHY_RGMII_DELAY_800_PS,
  199. VSC_PHY_RGMII_DELAY_1100_PS,
  200. VSC_PHY_RGMII_DELAY_1700_PS,
  201. VSC_PHY_RGMII_DELAY_2000_PS,
  202. VSC_PHY_RGMII_DELAY_2300_PS,
  203. VSC_PHY_RGMII_DELAY_2600_PS,
  204. VSC_PHY_RGMII_DELAY_3400_PS,
  205. };
  206. /* MAC i/f Clock Edge Rage Control (Slew), See Reg27E2 */ enum
  207. vsc_phy_clk_slew {
  208. VSC_PHY_CLK_SLEW_RATE_0,
  209. VSC_PHY_CLK_SLEW_RATE_1,
  210. VSC_PHY_CLK_SLEW_RATE_2,
  211. VSC_PHY_CLK_SLEW_RATE_3,
  212. VSC_PHY_CLK_SLEW_RATE_4,
  213. VSC_PHY_CLK_SLEW_RATE_5,
  214. VSC_PHY_CLK_SLEW_RATE_6,
  215. VSC_PHY_CLK_SLEW_RATE_7,
  216. };
  217. struct vsc85xx_priv {
  218. int (*config_pre)(struct phy_device *phydev);
  219. };
  220. static void vsc8584_csr_write(struct mii_dev *bus, int phy0, u16 addr, u32 val)
  221. {
  222. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18,
  223. val >> 16);
  224. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17,
  225. val & GENMASK(15, 0));
  226. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
  227. MSCC_PHY_TR_16_WRITE | addr);
  228. }
  229. static int vsc8584_cmd(struct mii_dev *bus, int phy, u16 val)
  230. {
  231. unsigned long deadline;
  232. u16 reg_val;
  233. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  234. MSCC_PHY_PAGE_GPIO);
  235. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_PROC_CMD,
  236. PROC_CMD_NCOMPLETED | val);
  237. deadline = timer_get_us() + PROC_CMD_NCOMPLETED_TIMEOUT_MS * 1000;
  238. do {
  239. reg_val = bus->read(bus, phy, MDIO_DEVAD_NONE,
  240. MSCC_PHY_PROC_CMD);
  241. } while (timer_get_us() <= deadline &&
  242. (reg_val & PROC_CMD_NCOMPLETED) &&
  243. !(reg_val & PROC_CMD_FAILED));
  244. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  245. MSCC_PHY_PAGE_STD);
  246. if (reg_val & PROC_CMD_FAILED)
  247. return -EIO;
  248. if (reg_val & PROC_CMD_NCOMPLETED)
  249. return -ETIMEDOUT;
  250. return 0;
  251. }
  252. static int vsc8584_micro_deassert_reset(struct mii_dev *bus, int phy,
  253. bool patch_en)
  254. {
  255. u32 enable, release;
  256. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  257. MSCC_PHY_PAGE_GPIO);
  258. enable = RUN_FROM_INT_ROM | MICRO_CLK_EN | DW8051_CLK_EN;
  259. release = MICRO_NSOFT_RESET | RUN_FROM_INT_ROM | DW8051_CLK_EN |
  260. MICRO_CLK_EN;
  261. if (patch_en) {
  262. enable |= MICRO_PATCH_EN;
  263. release |= MICRO_PATCH_EN;
  264. /* Clear all patches */
  265. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL,
  266. READ_RAM);
  267. }
  268. /*
  269. * Enable 8051 Micro clock; CLEAR/SET patch present; disable PRAM clock
  270. * override and addr. auto-incr; operate at 125 MHz
  271. */
  272. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS, enable);
  273. /* Release 8051 Micro SW reset */
  274. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS, release);
  275. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  276. MSCC_PHY_PAGE_STD);
  277. return 0;
  278. }
  279. static int vsc8584_micro_assert_reset(struct mii_dev *bus, int phy)
  280. {
  281. int ret;
  282. u16 reg;
  283. ret = vsc8584_cmd(bus, phy, PROC_CMD_NOP);
  284. if (ret)
  285. return ret;
  286. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  287. MSCC_PHY_PAGE_GPIO);
  288. reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL);
  289. reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
  290. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, reg);
  291. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_TRAP_ROM_ADDR(4), 0x005b);
  292. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PATCH_RAM_ADDR(4), 0x005b);
  293. reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL);
  294. reg |= EN_PATCH_RAM_TRAP_ADDR(4);
  295. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, reg);
  296. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_PROC_CMD, PROC_CMD_NOP);
  297. reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS);
  298. reg &= ~MICRO_NSOFT_RESET;
  299. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS, reg);
  300. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_PROC_CMD,
  301. PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_SGMII_PORT(0) |
  302. PROC_CMD_NO_MAC_CONF | PROC_CMD_READ);
  303. reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL);
  304. reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
  305. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, reg);
  306. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  307. MSCC_PHY_PAGE_STD);
  308. return 0;
  309. }
  310. static const u8 fw_patch_vsc8584[] = {
  311. 0xe8, 0x59, 0x02, 0xe8, 0x12, 0x02, 0xe8, 0x42, 0x02, 0xe8, 0x5a, 0x02,
  312. 0xe8, 0x5b, 0x02, 0xe8, 0x5c, 0xe5, 0x69, 0x54, 0x0f, 0x24, 0xf7, 0x60,
  313. 0x27, 0x24, 0xfc, 0x60, 0x23, 0x24, 0x08, 0x70, 0x14, 0xe5, 0x69, 0xae,
  314. 0x68, 0x78, 0x04, 0xce, 0xa2, 0xe7, 0x13, 0xce, 0x13, 0xd8, 0xf8, 0x7e,
  315. 0x00, 0x54, 0x0f, 0x80, 0x00, 0x7b, 0x01, 0x7a, 0x00, 0x7d, 0xee, 0x7f,
  316. 0x92, 0x12, 0x50, 0xee, 0x22, 0xe4, 0xf5, 0x10, 0x85, 0x10, 0xfb, 0x7d,
  317. 0x1c, 0xe4, 0xff, 0x12, 0x59, 0xea, 0x05, 0x10, 0xe5, 0x10, 0xc3, 0x94,
  318. 0x04, 0x40, 0xed, 0x22, 0x22, 0x22, 0x22, 0x22,
  319. };
  320. static int vsc8584_get_fw_crc(struct mii_dev *bus, int phy, u16 start,
  321. u16 *crc, const u8 *fw_patch, int fw_size)
  322. {
  323. int ret;
  324. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  325. MSCC_PHY_PAGE_EXT1);
  326. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_VERIPHY_CNTL_2, start);
  327. /* Add one byte to size for the one added by the patch_fw function */
  328. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_VERIPHY_CNTL_3,
  329. fw_size + 1);
  330. ret = vsc8584_cmd(bus, phy, PROC_CMD_CRC16);
  331. if (ret)
  332. goto out;
  333. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  334. MSCC_PHY_PAGE_EXT1);
  335. *crc = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_VERIPHY_CNTL_2);
  336. out:
  337. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  338. MSCC_PHY_PAGE_STD);
  339. return ret;
  340. }
  341. static int vsc8584_patch_fw(struct mii_dev *bus, int phy, const u8 *fw_patch,
  342. int fw_size)
  343. {
  344. int i, ret;
  345. ret = vsc8584_micro_assert_reset(bus, phy);
  346. if (ret) {
  347. pr_err("%s: failed to assert reset of micro\n", __func__);
  348. return ret;
  349. }
  350. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  351. MSCC_PHY_PAGE_GPIO);
  352. /*
  353. * Hold 8051 Micro in SW Reset, Enable auto incr address and patch clock
  354. * Disable the 8051 Micro clock
  355. */
  356. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS,
  357. RUN_FROM_INT_ROM | AUTOINC_ADDR | PATCH_RAM_CLK |
  358. MICRO_CLK_EN | MICRO_CLK_DIVIDE(2));
  359. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, READ_PRAM |
  360. INT_MEM_WRITE_EN | INT_MEM_DATA(2));
  361. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_ADDR, 0x0000);
  362. for (i = 0; i < fw_size; i++)
  363. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL,
  364. READ_PRAM | INT_MEM_WRITE_EN | fw_patch[i]);
  365. /* Clear internal memory access */
  366. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, READ_RAM);
  367. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  368. MSCC_PHY_PAGE_STD);
  369. return 0;
  370. }
  371. static int vsc8584_config_pre_init(struct phy_device *phydev)
  372. {
  373. struct mii_dev *bus = phydev->bus;
  374. u16 reg, crc, phy0, addr;
  375. int ret;
  376. if ((phydev->phy_id & MSCC_DEV_REV_MASK) != VSC8584_REVB) {
  377. pr_warn("VSC8584 revA not officially supported, skipping firmware patching. Use at your own risk.\n");
  378. return 0;
  379. }
  380. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  381. MSCC_PHY_PAGE_EXT1);
  382. addr = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_4);
  383. addr >>= PHY_CNTL_4_ADDR_POS;
  384. reg = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_ACTIPHY_CNTL);
  385. if (reg & PHY_ADDR_REVERSED)
  386. phy0 = phydev->addr + addr;
  387. else
  388. phy0 = phydev->addr - addr;
  389. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  390. MSCC_PHY_PAGE_STD);
  391. /* all writes below are broadcasted to all PHYs in the same package */
  392. reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS);
  393. reg |= SMI_BROADCAST_WR_EN;
  394. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS, reg);
  395. /*
  396. * The below register writes are tweaking analog and electrical
  397. * configuration that were determined through characterization by PHY
  398. * engineers. These don't mean anything more than "these are the best
  399. * values".
  400. */
  401. reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_BYPASS_CONTROL);
  402. reg |= PARALLEL_DET_IGNORE_ADVERTISED;
  403. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_BYPASS_CONTROL, reg);
  404. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  405. MSCC_PHY_PAGE_EXT3);
  406. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_SERDES_TX_CRC_ERR_CNT,
  407. 0x2000);
  408. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  409. MSCC_PHY_PAGE_TEST);
  410. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_5, 0x1f20);
  411. reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8);
  412. reg |= TR_CLK_DISABLE;
  413. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8, reg);
  414. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  415. MSCC_PHY_PAGE_TR);
  416. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16, 0xafa4);
  417. reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18);
  418. reg &= ~0x007f;
  419. reg |= 0x0019;
  420. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18, reg);
  421. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16, 0x8fa4);
  422. vsc8584_csr_write(bus, phy0, 0x07fa, 0x0050100f);
  423. vsc8584_csr_write(bus, phy0, 0x1688, 0x00049f81);
  424. vsc8584_csr_write(bus, phy0, 0x0f90, 0x00688980);
  425. vsc8584_csr_write(bus, phy0, 0x03a4, 0x0000d8f0);
  426. vsc8584_csr_write(bus, phy0, 0x0fc0, 0x00000400);
  427. vsc8584_csr_write(bus, phy0, 0x0f82, 0x0012b002);
  428. vsc8584_csr_write(bus, phy0, 0x1686, 0x00000004);
  429. vsc8584_csr_write(bus, phy0, 0x168c, 0x00d2c46f);
  430. vsc8584_csr_write(bus, phy0, 0x17a2, 0x00000620);
  431. vsc8584_csr_write(bus, phy0, 0x16a0, 0x00eeffdd);
  432. vsc8584_csr_write(bus, phy0, 0x16a6, 0x00071448);
  433. vsc8584_csr_write(bus, phy0, 0x16a4, 0x0013132f);
  434. vsc8584_csr_write(bus, phy0, 0x16a8, 0x00000000);
  435. vsc8584_csr_write(bus, phy0, 0x0ffc, 0x00c0a028);
  436. vsc8584_csr_write(bus, phy0, 0x0fe8, 0x0091b06c);
  437. vsc8584_csr_write(bus, phy0, 0x0fea, 0x00041600);
  438. vsc8584_csr_write(bus, phy0, 0x0f80, 0x00fffaff);
  439. vsc8584_csr_write(bus, phy0, 0x0fec, 0x00901809);
  440. vsc8584_csr_write(bus, phy0, 0x0ffe, 0x00b01007);
  441. vsc8584_csr_write(bus, phy0, 0x16b0, 0x00eeff00);
  442. vsc8584_csr_write(bus, phy0, 0x16b2, 0x00007000);
  443. vsc8584_csr_write(bus, phy0, 0x16b4, 0x00000814);
  444. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  445. MSCC_PHY_PAGE_EXT2);
  446. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
  447. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  448. MSCC_PHY_PAGE_TR);
  449. vsc8584_csr_write(bus, phy0, 0x0486, 0x0008a518);
  450. vsc8584_csr_write(bus, phy0, 0x0488, 0x006dc696);
  451. vsc8584_csr_write(bus, phy0, 0x048a, 0x00000912);
  452. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  453. MSCC_PHY_PAGE_TEST);
  454. reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8);
  455. reg &= ~TR_CLK_DISABLE;
  456. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8, reg);
  457. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  458. MSCC_PHY_PAGE_STD);
  459. /* end of write broadcasting */
  460. reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS);
  461. reg &= ~SMI_BROADCAST_WR_EN;
  462. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS, reg);
  463. ret = vsc8584_get_fw_crc(bus, phy0,
  464. MSCC_VSC8584_REVB_INT8051_FW_START_ADDR, &crc,
  465. fw_patch_vsc8584,
  466. ARRAY_SIZE(fw_patch_vsc8584));
  467. if (ret)
  468. goto out;
  469. if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC) {
  470. debug("FW CRC is not the expected one, patching FW...\n");
  471. if (vsc8584_patch_fw(bus, phy0, fw_patch_vsc8584,
  472. ARRAY_SIZE(fw_patch_vsc8584)))
  473. pr_warn("failed to patch FW, expect non-optimal device\n");
  474. }
  475. vsc8584_micro_deassert_reset(bus, phy0, false);
  476. ret = vsc8584_get_fw_crc(bus, phy0,
  477. MSCC_VSC8584_REVB_INT8051_FW_START_ADDR, &crc,
  478. fw_patch_vsc8584,
  479. ARRAY_SIZE(fw_patch_vsc8584));
  480. if (ret)
  481. goto out;
  482. if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC)
  483. pr_warn("FW CRC after patching is not the expected one, expect non-optimal device\n");
  484. ret = vsc8584_micro_assert_reset(bus, phy0);
  485. if (ret)
  486. goto out;
  487. vsc8584_micro_deassert_reset(bus, phy0, true);
  488. out:
  489. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  490. MSCC_PHY_PAGE_STD);
  491. return ret;
  492. }
  493. static int mscc_vsc8531_vsc8541_init_scripts(struct phy_device *phydev)
  494. {
  495. u16 reg_val;
  496. /* Set to Access Token Ring Registers */
  497. phy_write(phydev, MDIO_DEVAD_NONE,
  498. MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
  499. /* Update LinkDetectCtrl default to optimized values */
  500. /* Determined during Silicon Validation Testing */
  501. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
  502. (MSCC_PHY_TR_LINKDETCTRL_ADDR | MSCC_PHY_TR_16_READ));
  503. reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17);
  504. reg_val = bitfield_replace(reg_val, MSCC_PHY_TR_LINKDETCTRL_POS,
  505. MSCC_PHY_TR_LINKDETCTRL_WIDTH,
  506. MSCC_PHY_TR_LINKDETCTRL_VAL);
  507. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17, reg_val);
  508. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
  509. (MSCC_PHY_TR_LINKDETCTRL_ADDR | MSCC_PHY_TR_16_WRITE));
  510. /* Update VgaThresh100 defaults to optimized values */
  511. /* Determined during Silicon Validation Testing */
  512. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
  513. (MSCC_PHY_TR_VGATHRESH100_ADDR | MSCC_PHY_TR_16_READ));
  514. reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18);
  515. reg_val = bitfield_replace(reg_val, MSCC_PHY_TR_VGATHRESH100_POS,
  516. MSCC_PHY_TR_VGATHRESH100_WIDTH,
  517. MSCC_PHY_TR_VGATHRESH100_VAL);
  518. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18, reg_val);
  519. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
  520. (MSCC_PHY_TR_VGATHRESH100_ADDR | MSCC_PHY_TR_16_WRITE));
  521. /* Update VgaGain10 defaults to optimized values */
  522. /* Determined during Silicon Validation Testing */
  523. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
  524. (MSCC_PHY_TR_VGAGAIN10_ADDR | MSCC_PHY_TR_16_READ));
  525. reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18);
  526. reg_val = bitfield_replace(reg_val, MSCC_PHY_TR_VGAGAIN10_U_POS,
  527. MSCC_PHY_TR_VGAGAIN10_U_WIDTH,
  528. MSCC_PHY_TR_VGAGAIN10_U_VAL);
  529. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18, reg_val);
  530. reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17);
  531. reg_val = bitfield_replace(reg_val, MSCC_PHY_TR_VGAGAIN10_L_POS,
  532. MSCC_PHY_TR_VGAGAIN10_L_WIDTH,
  533. MSCC_PHY_TR_VGAGAIN10_L_VAL);
  534. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17, reg_val);
  535. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
  536. (MSCC_PHY_TR_VGAGAIN10_ADDR | MSCC_PHY_TR_16_WRITE));
  537. /* Set back to Access Standard Page Registers */
  538. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  539. MSCC_PHY_PAGE_STD);
  540. return 0;
  541. }
  542. static int mscc_parse_status(struct phy_device *phydev)
  543. {
  544. u16 speed;
  545. u16 mii_reg;
  546. mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_AUX_CNTRL_STAT_REG);
  547. if (mii_reg & MIIM_AUX_CNTRL_STAT_F_DUPLEX)
  548. phydev->duplex = DUPLEX_FULL;
  549. else
  550. phydev->duplex = DUPLEX_HALF;
  551. speed = mii_reg & MIIM_AUX_CNTRL_STAT_SPEED_MASK;
  552. speed = speed >> MIIM_AUX_CNTRL_STAT_SPEED_POS;
  553. switch (speed) {
  554. case MIIM_AUX_CNTRL_STAT_SPEED_1000M:
  555. phydev->speed = SPEED_1000;
  556. break;
  557. case MIIM_AUX_CNTRL_STAT_SPEED_100M:
  558. phydev->speed = SPEED_100;
  559. break;
  560. case MIIM_AUX_CNTRL_STAT_SPEED_10M:
  561. phydev->speed = SPEED_10;
  562. break;
  563. default:
  564. phydev->speed = SPEED_10;
  565. break;
  566. }
  567. return 0;
  568. }
  569. static int mscc_startup(struct phy_device *phydev)
  570. {
  571. int retval;
  572. retval = genphy_update_link(phydev);
  573. if (retval)
  574. return retval;
  575. return mscc_parse_status(phydev);
  576. }
  577. static int mscc_phy_soft_reset(struct phy_device *phydev)
  578. {
  579. int retval = 0;
  580. u16 timeout = MSCC_PHY_RESET_TIMEOUT;
  581. u16 reg_val = 0;
  582. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  583. MSCC_PHY_PAGE_STD);
  584. reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
  585. phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, (reg_val | BMCR_RESET));
  586. reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
  587. while ((reg_val & BMCR_RESET) && (timeout > 0)) {
  588. reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
  589. timeout--;
  590. udelay(1000); /* 1 ms */
  591. }
  592. if (timeout == 0) {
  593. printf("MSCC PHY Soft_Reset Error: mac i/f = 0x%x\n",
  594. phydev->interface);
  595. retval = -ETIME;
  596. }
  597. return retval;
  598. }
  599. static int vsc8531_vsc8541_mac_config(struct phy_device *phydev)
  600. {
  601. u16 reg_val = 0;
  602. u16 mac_if = 0;
  603. u16 rx_clk_out = 0;
  604. /* For VSC8530/31 the only MAC modes are RMII/RGMII. */
  605. /* For VSC8540/41 the only MAC modes are (G)MII and RMII/RGMII. */
  606. /* Setup MAC Configuration */
  607. switch (phydev->interface) {
  608. case PHY_INTERFACE_MODE_MII:
  609. case PHY_INTERFACE_MODE_GMII:
  610. /* Set Reg23.12:11=0 */
  611. mac_if = MAC_IF_SELECTION_GMII;
  612. /* Set Reg20E2.11=1 */
  613. rx_clk_out = RX_CLK_OUT_DISABLE;
  614. break;
  615. case PHY_INTERFACE_MODE_RMII:
  616. /* Set Reg23.12:11=1 */
  617. mac_if = MAC_IF_SELECTION_RMII;
  618. /* Set Reg20E2.11=0 */
  619. rx_clk_out = RX_CLK_OUT_NORMAL;
  620. break;
  621. case PHY_INTERFACE_MODE_RGMII:
  622. /* Set Reg23.12:11=2 */
  623. mac_if = MAC_IF_SELECTION_RGMII;
  624. /* Set Reg20E2.11=0 */
  625. rx_clk_out = RX_CLK_OUT_NORMAL;
  626. break;
  627. default:
  628. printf("MSCC PHY - INVALID MAC i/f Config: mac i/f = 0x%x\n",
  629. phydev->interface);
  630. return -EINVAL;
  631. }
  632. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  633. MSCC_PHY_PAGE_STD);
  634. reg_val = phy_read(phydev, MDIO_DEVAD_NONE,
  635. MSCC_PHY_EXT_PHY_CNTL_1_REG);
  636. /* Set MAC i/f bits Reg23.12:11 */
  637. reg_val = bitfield_replace(reg_val, MAC_IF_SELECTION_POS,
  638. MAC_IF_SELECTION_WIDTH, mac_if);
  639. /* Update Reg23.12:11 */
  640. phy_write(phydev, MDIO_DEVAD_NONE,
  641. MSCC_PHY_EXT_PHY_CNTL_1_REG, reg_val);
  642. /* Setup ExtPg_2 Register Access */
  643. phy_write(phydev, MDIO_DEVAD_NONE,
  644. MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXT2);
  645. /* Read Reg20E2 */
  646. reg_val = phy_read(phydev, MDIO_DEVAD_NONE,
  647. MSCC_PHY_RGMII_CNTL_REG);
  648. reg_val = bitfield_replace(reg_val, RX_CLK_OUT_POS,
  649. RX_CLK_OUT_WIDTH, rx_clk_out);
  650. /* Update Reg20E2.11 */
  651. phy_write(phydev, MDIO_DEVAD_NONE,
  652. MSCC_PHY_RGMII_CNTL_REG, reg_val);
  653. /* Before leaving - Change back to Std Page Register Access */
  654. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  655. MSCC_PHY_PAGE_STD);
  656. return 0;
  657. }
  658. static int vsc8531_config(struct phy_device *phydev)
  659. {
  660. int retval = -EINVAL;
  661. u16 reg_val;
  662. u16 rmii_clk_out;
  663. enum vsc_phy_rgmii_skew rx_clk_skew = VSC_PHY_RGMII_DELAY_1700_PS;
  664. enum vsc_phy_rgmii_skew tx_clk_skew = VSC_PHY_RGMII_DELAY_800_PS;
  665. enum vsc_phy_clk_slew edge_rate = VSC_PHY_CLK_SLEW_RATE_4;
  666. /* For VSC8530/31 and VSC8540/41 the init scripts are the same */
  667. mscc_vsc8531_vsc8541_init_scripts(phydev);
  668. /* For VSC8530/31 the only MAC modes are RMII/RGMII. */
  669. switch (phydev->interface) {
  670. case PHY_INTERFACE_MODE_RMII:
  671. case PHY_INTERFACE_MODE_RGMII:
  672. retval = vsc8531_vsc8541_mac_config(phydev);
  673. if (retval != 0)
  674. return retval;
  675. retval = mscc_phy_soft_reset(phydev);
  676. if (retval != 0)
  677. return retval;
  678. break;
  679. default:
  680. printf("PHY 8530/31 MAC i/f Config Error: mac i/f = 0x%x\n",
  681. phydev->interface);
  682. return -EINVAL;
  683. }
  684. /* Default RMII Clk Output to 0=OFF/1=ON */
  685. rmii_clk_out = 0;
  686. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  687. MSCC_PHY_PAGE_EXT2);
  688. reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG);
  689. /* Reg20E2 - Update RGMII RX_Clk Skews. */
  690. reg_val = bitfield_replace(reg_val, RGMII_RX_CLK_DELAY_POS,
  691. RGMII_RX_CLK_DELAY_WIDTH, rx_clk_skew);
  692. /* Reg20E2 - Update RGMII TX_Clk Skews. */
  693. reg_val = bitfield_replace(reg_val, RGMII_TX_CLK_DELAY_POS,
  694. RGMII_TX_CLK_DELAY_WIDTH, tx_clk_skew);
  695. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG, reg_val);
  696. reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL);
  697. /* Reg27E2 - Update Clk Slew Rate. */
  698. reg_val = bitfield_replace(reg_val, EDGE_RATE_CNTL_POS,
  699. EDGE_RATE_CNTL_WIDTH, edge_rate);
  700. /* Reg27E2 - Update RMII Clk Out. */
  701. reg_val = bitfield_replace(reg_val, RMII_CLK_OUT_ENABLE_POS,
  702. RMII_CLK_OUT_ENABLE_WIDTH, rmii_clk_out);
  703. /* Update Reg27E2 */
  704. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL, reg_val);
  705. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  706. MSCC_PHY_PAGE_STD);
  707. return genphy_config_aneg(phydev);
  708. }
  709. static int vsc8541_config(struct phy_device *phydev)
  710. {
  711. int retval = -EINVAL;
  712. u16 reg_val;
  713. u16 rmii_clk_out;
  714. enum vsc_phy_rgmii_skew rx_clk_skew = VSC_PHY_RGMII_DELAY_1700_PS;
  715. enum vsc_phy_rgmii_skew tx_clk_skew = VSC_PHY_RGMII_DELAY_800_PS;
  716. enum vsc_phy_clk_slew edge_rate = VSC_PHY_CLK_SLEW_RATE_4;
  717. /* For VSC8530/31 and VSC8540/41 the init scripts are the same */
  718. mscc_vsc8531_vsc8541_init_scripts(phydev);
  719. /* For VSC8540/41 the only MAC modes are (G)MII and RMII/RGMII. */
  720. switch (phydev->interface) {
  721. case PHY_INTERFACE_MODE_MII:
  722. case PHY_INTERFACE_MODE_GMII:
  723. case PHY_INTERFACE_MODE_RMII:
  724. case PHY_INTERFACE_MODE_RGMII:
  725. retval = vsc8531_vsc8541_mac_config(phydev);
  726. if (retval != 0)
  727. return retval;
  728. retval = mscc_phy_soft_reset(phydev);
  729. if (retval != 0)
  730. return retval;
  731. break;
  732. default:
  733. printf("PHY 8541 MAC i/f config Error: mac i/f = 0x%x\n",
  734. phydev->interface);
  735. return -EINVAL;
  736. }
  737. /* Default RMII Clk Output to 0=OFF/1=ON */
  738. rmii_clk_out = 0;
  739. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  740. MSCC_PHY_PAGE_EXT2);
  741. reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG);
  742. /* Reg20E2 - Update RGMII RX_Clk Skews. */
  743. reg_val = bitfield_replace(reg_val, RGMII_RX_CLK_DELAY_POS,
  744. RGMII_RX_CLK_DELAY_WIDTH, rx_clk_skew);
  745. /* Reg20E2 - Update RGMII TX_Clk Skews. */
  746. reg_val = bitfield_replace(reg_val, RGMII_TX_CLK_DELAY_POS,
  747. RGMII_TX_CLK_DELAY_WIDTH, tx_clk_skew);
  748. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG, reg_val);
  749. reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL);
  750. /* Reg27E2 - Update Clk Slew Rate. */
  751. reg_val = bitfield_replace(reg_val, EDGE_RATE_CNTL_POS,
  752. EDGE_RATE_CNTL_WIDTH, edge_rate);
  753. /* Reg27E2 - Update RMII Clk Out. */
  754. reg_val = bitfield_replace(reg_val, RMII_CLK_OUT_ENABLE_POS,
  755. RMII_CLK_OUT_ENABLE_WIDTH, rmii_clk_out);
  756. /* Update Reg27E2 */
  757. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL, reg_val);
  758. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  759. MSCC_PHY_PAGE_STD);
  760. return genphy_config_aneg(phydev);
  761. }
  762. static int vsc8584_config_init(struct phy_device *phydev)
  763. {
  764. struct vsc85xx_priv *priv = phydev->priv;
  765. int ret;
  766. u16 addr;
  767. u16 reg_val;
  768. u16 val;
  769. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  770. MSCC_PHY_PAGE_EXT1);
  771. addr = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_4);
  772. addr >>= PHY_CNTL_4_ADDR_POS;
  773. ret = priv->config_pre(phydev);
  774. if (ret)
  775. return ret;
  776. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  777. MSCC_PHY_PAGE_GPIO);
  778. if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
  779. val = MAC_CFG_QSGMII;
  780. else
  781. val = MAC_CFG_SGMII;
  782. reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_MAC_CFG_FASTLINK);
  783. reg_val &= ~MAC_CFG_MASK;
  784. reg_val |= val;
  785. ret = phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_MAC_CFG_FASTLINK,
  786. reg_val);
  787. if (ret)
  788. return ret;
  789. reg_val = PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_RST_CONF_PORT |
  790. PROC_CMD_READ_MOD_WRITE_PORT;
  791. if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
  792. reg_val |= PROC_CMD_QSGMII_MAC;
  793. else
  794. reg_val |= PROC_CMD_SGMII_MAC;
  795. ret = vsc8584_cmd(phydev->bus, phydev->addr, reg_val);
  796. if (ret)
  797. return ret;
  798. mdelay(10);
  799. /* Disable SerDes for 100Base-FX */
  800. ret = vsc8584_cmd(phydev->bus, phydev->addr, PROC_CMD_FIBER_MEDIA_CONF |
  801. PROC_CMD_FIBER_PORT(addr) | PROC_CMD_FIBER_DISABLE |
  802. PROC_CMD_READ_MOD_WRITE_PORT |
  803. PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_100BASE_FX);
  804. if (ret)
  805. return ret;
  806. /* Disable SerDes for 1000Base-X */
  807. ret = vsc8584_cmd(phydev->bus, phydev->addr, PROC_CMD_FIBER_MEDIA_CONF |
  808. PROC_CMD_FIBER_PORT(addr) | PROC_CMD_FIBER_DISABLE |
  809. PROC_CMD_READ_MOD_WRITE_PORT |
  810. PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_1000BASE_X);
  811. if (ret)
  812. return ret;
  813. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  814. MSCC_PHY_PAGE_STD);
  815. reg_val = phy_read(phydev, MDIO_DEVAD_NONE,
  816. MSCC_PHY_EXT_PHY_CNTL_1_REG);
  817. reg_val &= ~(MEDIA_OP_MODE_MASK | VSC8584_MAC_IF_SELECTION_MASK);
  818. reg_val |= MEDIA_OP_MODE_COPPER |
  819. (VSC8584_MAC_IF_SELECTION_SGMII <<
  820. VSC8584_MAC_IF_SELECTION_POS);
  821. ret = phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_1_REG,
  822. reg_val);
  823. ret = mscc_phy_soft_reset(phydev);
  824. if (ret != 0)
  825. return ret;
  826. return genphy_config(phydev);
  827. }
  828. static struct vsc85xx_priv vsc8584_priv = {
  829. .config_pre = vsc8584_config_pre_init,
  830. };
  831. static int vsc8584_config(struct phy_device *phydev)
  832. {
  833. phydev->priv = &vsc8584_priv;
  834. return vsc8584_config_init(phydev);
  835. }
  836. static struct phy_driver VSC8530_driver = {
  837. .name = "Microsemi VSC8530",
  838. .uid = PHY_ID_VSC8530,
  839. .mask = 0x000ffff0,
  840. .features = PHY_BASIC_FEATURES,
  841. .config = &vsc8531_config,
  842. .startup = &mscc_startup,
  843. .shutdown = &genphy_shutdown,
  844. };
  845. static struct phy_driver VSC8531_driver = {
  846. .name = "Microsemi VSC8531",
  847. .uid = PHY_ID_VSC8531,
  848. .mask = 0x000ffff0,
  849. .features = PHY_GBIT_FEATURES,
  850. .config = &vsc8531_config,
  851. .startup = &mscc_startup,
  852. .shutdown = &genphy_shutdown,
  853. };
  854. static struct phy_driver VSC8540_driver = {
  855. .name = "Microsemi VSC8540",
  856. .uid = PHY_ID_VSC8540,
  857. .mask = 0x000ffff0,
  858. .features = PHY_BASIC_FEATURES,
  859. .config = &vsc8541_config,
  860. .startup = &mscc_startup,
  861. .shutdown = &genphy_shutdown,
  862. };
  863. static struct phy_driver VSC8541_driver = {
  864. .name = "Microsemi VSC8541",
  865. .uid = PHY_ID_VSC8541,
  866. .mask = 0x000ffff0,
  867. .features = PHY_GBIT_FEATURES,
  868. .config = &vsc8541_config,
  869. .startup = &mscc_startup,
  870. .shutdown = &genphy_shutdown,
  871. };
  872. static struct phy_driver VSC8584_driver = {
  873. .name = "Microsemi VSC8584",
  874. .uid = PHY_ID_VSC8584,
  875. .mask = 0x000ffff0,
  876. .features = PHY_GBIT_FEATURES,
  877. .config = &vsc8584_config,
  878. .startup = &mscc_startup,
  879. .shutdown = &genphy_shutdown,
  880. };
  881. int phy_mscc_init(void)
  882. {
  883. phy_register(&VSC8530_driver);
  884. phy_register(&VSC8531_driver);
  885. phy_register(&VSC8540_driver);
  886. phy_register(&VSC8541_driver);
  887. phy_register(&VSC8584_driver);
  888. return 0;
  889. }