mscc.c 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629
  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 <log.h>
  12. #include <miiphy.h>
  13. #include <bitfield.h>
  14. #include <time.h>
  15. #include <linux/bitops.h>
  16. #include <linux/delay.h>
  17. /* Microsemi PHY ID's */
  18. #define PHY_ID_VSC8530 0x00070560
  19. #define PHY_ID_VSC8531 0x00070570
  20. #define PHY_ID_VSC8502 0x00070630
  21. #define PHY_ID_VSC8540 0x00070760
  22. #define PHY_ID_VSC8541 0x00070770
  23. #define PHY_ID_VSC8574 0x000704a0
  24. #define PHY_ID_VSC8584 0x000707c0
  25. /* Microsemi VSC85xx PHY Register Pages */
  26. #define MSCC_EXT_PAGE_ACCESS 31 /* Page Access Register */
  27. #define MSCC_PHY_PAGE_STD 0x0000 /* Standard registers */
  28. #define MSCC_PHY_PAGE_EXT1 0x0001 /* Extended registers - page 1 */
  29. #define MSCC_PHY_PAGE_EXT2 0x0002 /* Extended registers - page 2 */
  30. #define MSCC_PHY_PAGE_EXT3 0x0003 /* Extended registers - page 3 */
  31. #define MSCC_PHY_PAGE_EXT4 0x0004 /* Extended registers - page 4 */
  32. #define MSCC_PHY_PAGE_GPIO 0x0010 /* GPIO registers */
  33. #define MSCC_PHY_PAGE_TEST 0x2A30 /* TEST Page registers */
  34. #define MSCC_PHY_PAGE_TR 0x52B5 /* Token Ring Page registers */
  35. /* Std Page Register 18 */
  36. #define MSCC_PHY_BYPASS_CONTROL 18
  37. #define PARALLEL_DET_IGNORE_ADVERTISED BIT(3)
  38. /* Std Page Register 22 */
  39. #define MSCC_PHY_EXT_CNTL_STATUS 22
  40. #define SMI_BROADCAST_WR_EN BIT(0)
  41. /* Std Page Register 24 */
  42. #define MSCC_PHY_EXT_PHY_CNTL_2 24
  43. /* Std Page Register 28 - PHY AUX Control/Status */
  44. #define MIIM_AUX_CNTRL_STAT_REG 28
  45. #define MIIM_AUX_CNTRL_STAT_ACTIPHY_TO (0x0004)
  46. #define MIIM_AUX_CNTRL_STAT_F_DUPLEX (0x0020)
  47. #define MIIM_AUX_CNTRL_STAT_SPEED_MASK (0x0018)
  48. #define MIIM_AUX_CNTRL_STAT_SPEED_POS (3)
  49. #define MIIM_AUX_CNTRL_STAT_SPEED_10M (0x0)
  50. #define MIIM_AUX_CNTRL_STAT_SPEED_100M (0x1)
  51. #define MIIM_AUX_CNTRL_STAT_SPEED_1000M (0x2)
  52. /* Std Page Register 23 - Extended PHY CTRL_1 */
  53. #define MSCC_PHY_EXT_PHY_CNTL_1_REG 23
  54. #define MAC_IF_SELECTION_MASK (0x1800)
  55. #define MAC_IF_SELECTION_GMII (0)
  56. #define MAC_IF_SELECTION_RMII (1)
  57. #define MAC_IF_SELECTION_RGMII (2)
  58. #define MAC_IF_SELECTION_POS (11)
  59. #define MAC_IF_SELECTION_WIDTH (2)
  60. #define VSC8584_MAC_IF_SELECTION_MASK BIT(12)
  61. #define VSC8584_MAC_IF_SELECTION_SGMII 0
  62. #define VSC8584_MAC_IF_SELECTION_1000BASEX 1
  63. #define VSC8584_MAC_IF_SELECTION_POS 12
  64. #define MEDIA_OP_MODE_MASK GENMASK(10, 8)
  65. #define MEDIA_OP_MODE_COPPER 0
  66. #define MEDIA_OP_MODE_SERDES 1
  67. #define MEDIA_OP_MODE_1000BASEX 2
  68. #define MEDIA_OP_MODE_100BASEFX 3
  69. #define MEDIA_OP_MODE_AMS_COPPER_SERDES 5
  70. #define MEDIA_OP_MODE_AMS_COPPER_1000BASEX 6
  71. #define MEDIA_OP_MODE_AMS_COPPER_100BASEFX 7
  72. #define MEDIA_OP_MODE_POS 8
  73. /* Extended Page 1 Register 20E1 */
  74. #define MSCC_PHY_ACTIPHY_CNTL 20
  75. #define PHY_ADDR_REVERSED BIT(9)
  76. /* Extended Page 1 Register 23E1 */
  77. #define MSCC_PHY_EXT_PHY_CNTL_4 23
  78. #define PHY_CNTL_4_ADDR_POS 11
  79. /* Extended Page 1 Register 25E1 */
  80. #define MSCC_PHY_VERIPHY_CNTL_2 25
  81. /* Extended Page 1 Register 26E1 */
  82. #define MSCC_PHY_VERIPHY_CNTL_3 26
  83. /* Extended Page 2 Register 16E2 */
  84. #define MSCC_PHY_CU_PMD_TX_CNTL 16
  85. /* Extended Page 2 Register 20E2 */
  86. #define MSCC_PHY_RGMII_CNTL_REG 20
  87. #define VSC_FAST_LINK_FAIL2_ENA_MASK (0x8000)
  88. #define RX_CLK_OUT_MASK (0x0800)
  89. #define RX_CLK_OUT_POS (11)
  90. #define RX_CLK_OUT_WIDTH (1)
  91. #define RX_CLK_OUT_NORMAL (0)
  92. #define RX_CLK_OUT_DISABLE (1)
  93. #define RGMII_RX_CLK_DELAY_POS (4)
  94. #define RGMII_RX_CLK_DELAY_WIDTH (3)
  95. #define RGMII_RX_CLK_DELAY_MASK (0x0070)
  96. #define RGMII_TX_CLK_DELAY_POS (0)
  97. #define RGMII_TX_CLK_DELAY_WIDTH (3)
  98. #define RGMII_TX_CLK_DELAY_MASK (0x0007)
  99. /* Extended Page 2 Register 27E2 */
  100. #define MSCC_PHY_WOL_MAC_CONTROL 27
  101. #define EDGE_RATE_CNTL_POS (5)
  102. #define EDGE_RATE_CNTL_WIDTH (3)
  103. #define EDGE_RATE_CNTL_MASK (0x00E0)
  104. #define RMII_CLK_OUT_ENABLE_POS (4)
  105. #define RMII_CLK_OUT_ENABLE_WIDTH (1)
  106. #define RMII_CLK_OUT_ENABLE_MASK (0x10)
  107. /* Extended Page 3 Register 22E3 */
  108. #define MSCC_PHY_SERDES_TX_CRC_ERR_CNT 22
  109. /* Extended page GPIO register 00G */
  110. #define MSCC_DW8051_CNTL_STATUS 0
  111. #define MICRO_NSOFT_RESET BIT(15)
  112. #define RUN_FROM_INT_ROM BIT(14)
  113. #define AUTOINC_ADDR BIT(13)
  114. #define PATCH_RAM_CLK BIT(12)
  115. #define MICRO_PATCH_EN BIT(7)
  116. #define DW8051_CLK_EN BIT(4)
  117. #define MICRO_CLK_EN BIT(3)
  118. #define MICRO_CLK_DIVIDE(x) ((x) >> 1)
  119. #define MSCC_DW8051_VLD_MASK 0xf1ff
  120. /* Extended page GPIO register 09G */
  121. #define MSCC_TRAP_ROM_ADDR(x) ((x) * 2 + 1)
  122. #define MSCC_TRAP_ROM_ADDR_SERDES_INIT 0x3eb7
  123. /* Extended page GPIO register 10G */
  124. #define MSCC_PATCH_RAM_ADDR(x) (((x) + 1) * 2)
  125. #define MSCC_PATCH_RAM_ADDR_SERDES_INIT 0x4012
  126. /* Extended page GPIO register 11G */
  127. #define MSCC_INT_MEM_ADDR 11
  128. /* Extended page GPIO register 12G */
  129. #define MSCC_INT_MEM_CNTL 12
  130. #define READ_SFR (BIT(14) | BIT(13))
  131. #define READ_PRAM BIT(14)
  132. #define READ_ROM BIT(13)
  133. #define READ_RAM (0x00 << 13)
  134. #define INT_MEM_WRITE_EN BIT(12)
  135. #define EN_PATCH_RAM_TRAP_ADDR(x) BIT((x) + 7)
  136. #define INT_MEM_DATA_M GENMASK(7, 0)
  137. #define INT_MEM_DATA(x) (INT_MEM_DATA_M & (x))
  138. /* Extended page GPIO register 13G */
  139. #define MSCC_CLKOUT_CNTL 13
  140. #define CLKOUT_ENABLE BIT(15)
  141. #define CLKOUT_FREQ_MASK GENMASK(14, 13)
  142. #define CLKOUT_FREQ_25M (0x0 << 13)
  143. #define CLKOUT_FREQ_50M (0x1 << 13)
  144. #define CLKOUT_FREQ_125M (0x2 << 13)
  145. /* Extended page GPIO register 18G */
  146. #define MSCC_PHY_PROC_CMD 18
  147. #define PROC_CMD_NCOMPLETED BIT(15)
  148. #define PROC_CMD_FAILED BIT(14)
  149. #define PROC_CMD_SGMII_PORT(x) ((x) << 8)
  150. #define PROC_CMD_FIBER_PORT(x) BIT(8 + (x) % 4)
  151. #define PROC_CMD_QSGMII_PORT (BIT(11) | BIT(10))
  152. #define PROC_CMD_RST_CONF_PORT BIT(7)
  153. #define PROC_CMD_RECONF_PORT (0 << 7)
  154. #define PROC_CMD_READ_MOD_WRITE_PORT BIT(6)
  155. #define PROC_CMD_WRITE BIT(6)
  156. #define PROC_CMD_READ (0 << 6)
  157. #define PROC_CMD_FIBER_DISABLE BIT(5)
  158. #define PROC_CMD_FIBER_100BASE_FX BIT(4)
  159. #define PROC_CMD_FIBER_1000BASE_X (0 << 4)
  160. #define PROC_CMD_SGMII_MAC (BIT(5) | BIT(4))
  161. #define PROC_CMD_QSGMII_MAC BIT(5)
  162. #define PROC_CMD_NO_MAC_CONF (0x00 << 4)
  163. #define PROC_CMD_1588_DEFAULT_INIT BIT(4)
  164. #define PROC_CMD_NOP GENMASK(3, 0)
  165. #define PROC_CMD_PHY_INIT (BIT(3) | BIT(1))
  166. #define PROC_CMD_CRC16 BIT(3)
  167. #define PROC_CMD_FIBER_MEDIA_CONF BIT(0)
  168. #define PROC_CMD_MCB_ACCESS_MAC_CONF (0x0000 << 0)
  169. #define PROC_CMD_NCOMPLETED_TIMEOUT_MS 500
  170. /* Extended page GPIO register 19G */
  171. #define MSCC_PHY_MAC_CFG_FASTLINK 19
  172. #define MAC_CFG_MASK GENMASK(15, 14)
  173. #define MAC_CFG_SGMII (0x00 << 14)
  174. #define MAC_CFG_QSGMII BIT(14)
  175. /* Test Registers */
  176. #define MSCC_PHY_TEST_PAGE_5 5
  177. #define MSCC_PHY_TEST_PAGE_8 8
  178. #define TR_CLK_DISABLE BIT(15)
  179. #define MSCC_PHY_TEST_PAGE_9 9
  180. #define MSCC_PHY_TEST_PAGE_20 20
  181. #define MSCC_PHY_TEST_PAGE_24 24
  182. /* Token Ring Page 0x52B5 Registers */
  183. #define MSCC_PHY_REG_TR_ADDR_16 16
  184. #define MSCC_PHY_REG_TR_DATA_17 17
  185. #define MSCC_PHY_REG_TR_DATA_18 18
  186. /* Token Ring - Read Value in */
  187. #define MSCC_PHY_TR_16_READ (0xA000)
  188. /* Token Ring - Write Value out */
  189. #define MSCC_PHY_TR_16_WRITE (0x8000)
  190. /* Token Ring Registers */
  191. #define MSCC_PHY_TR_LINKDETCTRL_POS (3)
  192. #define MSCC_PHY_TR_LINKDETCTRL_WIDTH (2)
  193. #define MSCC_PHY_TR_LINKDETCTRL_VAL (3)
  194. #define MSCC_PHY_TR_LINKDETCTRL_MASK (0x0018)
  195. #define MSCC_PHY_TR_LINKDETCTRL_ADDR (0x07F8)
  196. #define MSCC_PHY_TR_VGATHRESH100_POS (0)
  197. #define MSCC_PHY_TR_VGATHRESH100_WIDTH (7)
  198. #define MSCC_PHY_TR_VGATHRESH100_VAL (0x0018)
  199. #define MSCC_PHY_TR_VGATHRESH100_MASK (0x007f)
  200. #define MSCC_PHY_TR_VGATHRESH100_ADDR (0x0FA4)
  201. #define MSCC_PHY_TR_VGAGAIN10_U_POS (0)
  202. #define MSCC_PHY_TR_VGAGAIN10_U_WIDTH (1)
  203. #define MSCC_PHY_TR_VGAGAIN10_U_MASK (0x0001)
  204. #define MSCC_PHY_TR_VGAGAIN10_U_VAL (0)
  205. #define MSCC_PHY_TR_VGAGAIN10_L_POS (12)
  206. #define MSCC_PHY_TR_VGAGAIN10_L_WIDTH (4)
  207. #define MSCC_PHY_TR_VGAGAIN10_L_MASK (0xf000)
  208. #define MSCC_PHY_TR_VGAGAIN10_L_VAL (0x0001)
  209. #define MSCC_PHY_TR_VGAGAIN10_ADDR (0x0F92)
  210. /* General Timeout Values */
  211. #define MSCC_PHY_RESET_TIMEOUT (100)
  212. #define MSCC_PHY_MICRO_TIMEOUT (500)
  213. #define VSC8584_REVB 0x0001
  214. #define MSCC_DEV_REV_MASK GENMASK(3, 0)
  215. #define MSCC_VSC8574_REVB_INT8051_FW_START_ADDR 0x4000
  216. #define MSCC_VSC8574_REVB_INT8051_FW_CRC 0x29e8
  217. #define MSCC_VSC8584_REVB_INT8051_FW_START_ADDR 0xe800
  218. #define MSCC_VSC8584_REVB_INT8051_FW_CRC 0xfb48
  219. /* RGMII/GMII Clock Delay (Skew) Options */ enum vsc_phy_rgmii_skew {
  220. VSC_PHY_RGMII_DELAY_200_PS,
  221. VSC_PHY_RGMII_DELAY_800_PS,
  222. VSC_PHY_RGMII_DELAY_1100_PS,
  223. VSC_PHY_RGMII_DELAY_1700_PS,
  224. VSC_PHY_RGMII_DELAY_2000_PS,
  225. VSC_PHY_RGMII_DELAY_2300_PS,
  226. VSC_PHY_RGMII_DELAY_2600_PS,
  227. VSC_PHY_RGMII_DELAY_3400_PS,
  228. };
  229. /* MAC i/f Clock Edge Rage Control (Slew), See Reg27E2 */ enum
  230. vsc_phy_clk_slew {
  231. VSC_PHY_CLK_SLEW_RATE_0,
  232. VSC_PHY_CLK_SLEW_RATE_1,
  233. VSC_PHY_CLK_SLEW_RATE_2,
  234. VSC_PHY_CLK_SLEW_RATE_3,
  235. VSC_PHY_CLK_SLEW_RATE_4,
  236. VSC_PHY_CLK_SLEW_RATE_5,
  237. VSC_PHY_CLK_SLEW_RATE_6,
  238. VSC_PHY_CLK_SLEW_RATE_7,
  239. };
  240. struct vsc85xx_priv {
  241. int (*config_pre)(struct phy_device *phydev);
  242. };
  243. static void vsc8584_csr_write(struct mii_dev *bus, int phy0, u16 addr, u32 val)
  244. {
  245. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18,
  246. val >> 16);
  247. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17,
  248. val & GENMASK(15, 0));
  249. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
  250. MSCC_PHY_TR_16_WRITE | addr);
  251. }
  252. static int vsc8584_cmd(struct mii_dev *bus, int phy, u16 val)
  253. {
  254. unsigned long deadline;
  255. u16 reg_val;
  256. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  257. MSCC_PHY_PAGE_GPIO);
  258. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_PROC_CMD,
  259. PROC_CMD_NCOMPLETED | val);
  260. deadline = timer_get_us() + PROC_CMD_NCOMPLETED_TIMEOUT_MS * 1000;
  261. do {
  262. reg_val = bus->read(bus, phy, MDIO_DEVAD_NONE,
  263. MSCC_PHY_PROC_CMD);
  264. } while (timer_get_us() <= deadline &&
  265. (reg_val & PROC_CMD_NCOMPLETED) &&
  266. !(reg_val & PROC_CMD_FAILED));
  267. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  268. MSCC_PHY_PAGE_STD);
  269. if (reg_val & PROC_CMD_FAILED)
  270. return -EIO;
  271. if (reg_val & PROC_CMD_NCOMPLETED)
  272. return -ETIMEDOUT;
  273. return 0;
  274. }
  275. static int vsc8584_micro_deassert_reset(struct mii_dev *bus, int phy,
  276. bool patch_en)
  277. {
  278. u32 enable, release;
  279. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  280. MSCC_PHY_PAGE_GPIO);
  281. enable = RUN_FROM_INT_ROM | MICRO_CLK_EN | DW8051_CLK_EN;
  282. release = MICRO_NSOFT_RESET | RUN_FROM_INT_ROM | DW8051_CLK_EN |
  283. MICRO_CLK_EN;
  284. if (patch_en) {
  285. enable |= MICRO_PATCH_EN;
  286. release |= MICRO_PATCH_EN;
  287. /* Clear all patches */
  288. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL,
  289. READ_RAM);
  290. }
  291. /*
  292. * Enable 8051 Micro clock; CLEAR/SET patch present; disable PRAM clock
  293. * override and addr. auto-incr; operate at 125 MHz
  294. */
  295. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS, enable);
  296. /* Release 8051 Micro SW reset */
  297. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS, release);
  298. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  299. MSCC_PHY_PAGE_STD);
  300. return 0;
  301. }
  302. static int vsc8584_micro_assert_reset(struct mii_dev *bus, int phy)
  303. {
  304. int ret;
  305. u16 reg;
  306. ret = vsc8584_cmd(bus, phy, PROC_CMD_NOP);
  307. if (ret)
  308. return ret;
  309. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  310. MSCC_PHY_PAGE_GPIO);
  311. reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL);
  312. reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
  313. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, reg);
  314. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_TRAP_ROM_ADDR(4), 0x005b);
  315. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PATCH_RAM_ADDR(4), 0x005b);
  316. reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL);
  317. reg |= EN_PATCH_RAM_TRAP_ADDR(4);
  318. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, reg);
  319. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_PROC_CMD, PROC_CMD_NOP);
  320. reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS);
  321. reg &= ~MICRO_NSOFT_RESET;
  322. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS, reg);
  323. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_PROC_CMD,
  324. PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_SGMII_PORT(0) |
  325. PROC_CMD_NO_MAC_CONF | PROC_CMD_READ);
  326. reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL);
  327. reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
  328. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, reg);
  329. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  330. MSCC_PHY_PAGE_STD);
  331. return 0;
  332. }
  333. static const u8 fw_patch_vsc8574[] = {
  334. 0x46, 0x4a, 0x02, 0x43, 0x37, 0x02, 0x46, 0x26, 0x02, 0x46, 0x77, 0x02,
  335. 0x45, 0x60, 0x02, 0x45, 0xaf, 0xed, 0xff, 0xe5, 0xfc, 0x54, 0x38, 0x64,
  336. 0x20, 0x70, 0x08, 0x65, 0xff, 0x70, 0x04, 0xed, 0x44, 0x80, 0xff, 0x22,
  337. 0x8f, 0x19, 0x7b, 0xbb, 0x7d, 0x0e, 0x7f, 0x04, 0x12, 0x3d, 0xd7, 0xef,
  338. 0x4e, 0x60, 0x03, 0x02, 0x41, 0xf9, 0xe4, 0xf5, 0x1a, 0x74, 0x01, 0x7e,
  339. 0x00, 0xa8, 0x1a, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8,
  340. 0xf9, 0xff, 0xef, 0x55, 0x19, 0x70, 0x03, 0x02, 0x41, 0xed, 0x85, 0x1a,
  341. 0xfb, 0x7b, 0xbb, 0xe4, 0xfd, 0xff, 0x12, 0x3d, 0xd7, 0xef, 0x4e, 0x60,
  342. 0x03, 0x02, 0x41, 0xed, 0xe5, 0x1a, 0x54, 0x02, 0x75, 0x1d, 0x00, 0x25,
  343. 0xe0, 0x25, 0xe0, 0xf5, 0x1c, 0xe4, 0x78, 0xc5, 0xf6, 0xd2, 0x0a, 0x12,
  344. 0x41, 0xfa, 0x7b, 0xff, 0x7d, 0x12, 0x7f, 0x07, 0x12, 0x3d, 0xd7, 0xef,
  345. 0x4e, 0x60, 0x03, 0x02, 0x41, 0xe7, 0xc2, 0x0a, 0x74, 0xc7, 0x25, 0x1a,
  346. 0xf9, 0x74, 0xe7, 0x25, 0x1a, 0xf8, 0xe6, 0x27, 0xf5, 0x1b, 0xe5, 0x1d,
  347. 0x24, 0x5b, 0x12, 0x45, 0xea, 0x12, 0x3e, 0xda, 0x7b, 0xfc, 0x7d, 0x11,
  348. 0x7f, 0x07, 0x12, 0x3d, 0xd7, 0x78, 0xcc, 0xef, 0xf6, 0x78, 0xc1, 0xe6,
  349. 0xfe, 0xef, 0xd3, 0x9e, 0x40, 0x06, 0x78, 0xcc, 0xe6, 0x78, 0xc1, 0xf6,
  350. 0x12, 0x41, 0xfa, 0x7b, 0xec, 0x7d, 0x12, 0x7f, 0x07, 0x12, 0x3d, 0xd7,
  351. 0x78, 0xcb, 0xef, 0xf6, 0xbf, 0x07, 0x06, 0x78, 0xc3, 0x76, 0x1a, 0x80,
  352. 0x1f, 0x78, 0xc5, 0xe6, 0xff, 0x60, 0x0f, 0xc3, 0xe5, 0x1b, 0x9f, 0xff,
  353. 0x78, 0xcb, 0xe6, 0x85, 0x1b, 0xf0, 0xa4, 0x2f, 0x80, 0x07, 0x78, 0xcb,
  354. 0xe6, 0x85, 0x1b, 0xf0, 0xa4, 0x78, 0xc3, 0xf6, 0xe4, 0x78, 0xc2, 0xf6,
  355. 0x78, 0xc2, 0xe6, 0xff, 0xc3, 0x08, 0x96, 0x40, 0x03, 0x02, 0x41, 0xd1,
  356. 0xef, 0x54, 0x03, 0x60, 0x33, 0x14, 0x60, 0x46, 0x24, 0xfe, 0x60, 0x42,
  357. 0x04, 0x70, 0x4b, 0xef, 0x24, 0x02, 0xff, 0xe4, 0x33, 0xfe, 0xef, 0x78,
  358. 0x02, 0xce, 0xa2, 0xe7, 0x13, 0xce, 0x13, 0xd8, 0xf8, 0xff, 0xe5, 0x1d,
  359. 0x24, 0x5c, 0xcd, 0xe5, 0x1c, 0x34, 0xf0, 0xcd, 0x2f, 0xff, 0xed, 0x3e,
  360. 0xfe, 0x12, 0x46, 0x0d, 0x7d, 0x11, 0x80, 0x0b, 0x78, 0xc2, 0xe6, 0x70,
  361. 0x04, 0x7d, 0x11, 0x80, 0x02, 0x7d, 0x12, 0x7f, 0x07, 0x12, 0x3e, 0x9a,
  362. 0x8e, 0x1e, 0x8f, 0x1f, 0x80, 0x03, 0xe5, 0x1e, 0xff, 0x78, 0xc5, 0xe6,
  363. 0x06, 0x24, 0xcd, 0xf8, 0xa6, 0x07, 0x78, 0xc2, 0x06, 0xe6, 0xb4, 0x1a,
  364. 0x0a, 0xe5, 0x1d, 0x24, 0x5c, 0x12, 0x45, 0xea, 0x12, 0x3e, 0xda, 0x78,
  365. 0xc5, 0xe6, 0x65, 0x1b, 0x70, 0x82, 0x75, 0xdb, 0x20, 0x75, 0xdb, 0x28,
  366. 0x12, 0x46, 0x02, 0x12, 0x46, 0x02, 0xe5, 0x1a, 0x12, 0x45, 0xf5, 0xe5,
  367. 0x1a, 0xc3, 0x13, 0x12, 0x45, 0xf5, 0x78, 0xc5, 0x16, 0xe6, 0x24, 0xcd,
  368. 0xf8, 0xe6, 0xff, 0x7e, 0x08, 0x1e, 0xef, 0xa8, 0x06, 0x08, 0x80, 0x02,
  369. 0xc3, 0x13, 0xd8, 0xfc, 0xfd, 0xc4, 0x33, 0x54, 0xe0, 0xf5, 0xdb, 0xef,
  370. 0xa8, 0x06, 0x08, 0x80, 0x02, 0xc3, 0x13, 0xd8, 0xfc, 0xfd, 0xc4, 0x33,
  371. 0x54, 0xe0, 0x44, 0x08, 0xf5, 0xdb, 0xee, 0x70, 0xd8, 0x78, 0xc5, 0xe6,
  372. 0x70, 0xc8, 0x75, 0xdb, 0x10, 0x02, 0x40, 0xfd, 0x78, 0xc2, 0xe6, 0xc3,
  373. 0x94, 0x17, 0x50, 0x0e, 0xe5, 0x1d, 0x24, 0x62, 0x12, 0x42, 0x08, 0xe5,
  374. 0x1d, 0x24, 0x5c, 0x12, 0x42, 0x08, 0x20, 0x0a, 0x03, 0x02, 0x40, 0x76,
  375. 0x05, 0x1a, 0xe5, 0x1a, 0xc3, 0x94, 0x04, 0x50, 0x03, 0x02, 0x40, 0x3a,
  376. 0x22, 0xe5, 0x1d, 0x24, 0x5c, 0xff, 0xe5, 0x1c, 0x34, 0xf0, 0xfe, 0x12,
  377. 0x46, 0x0d, 0x22, 0xff, 0xe5, 0x1c, 0x34, 0xf0, 0xfe, 0x12, 0x46, 0x0d,
  378. 0x22, 0xe4, 0xf5, 0x19, 0x12, 0x46, 0x43, 0x20, 0xe7, 0x1e, 0x7b, 0xfe,
  379. 0x12, 0x42, 0xf9, 0xef, 0xc4, 0x33, 0x33, 0x54, 0xc0, 0xff, 0xc0, 0x07,
  380. 0x7b, 0x54, 0x12, 0x42, 0xf9, 0xd0, 0xe0, 0x4f, 0xff, 0x74, 0x2a, 0x25,
  381. 0x19, 0xf8, 0xa6, 0x07, 0x12, 0x46, 0x43, 0x20, 0xe7, 0x03, 0x02, 0x42,
  382. 0xdf, 0x54, 0x03, 0x64, 0x03, 0x70, 0x03, 0x02, 0x42, 0xcf, 0x7b, 0xcb,
  383. 0x12, 0x43, 0x2c, 0x8f, 0xfb, 0x7b, 0x30, 0x7d, 0x03, 0xe4, 0xff, 0x12,
  384. 0x3d, 0xd7, 0xc3, 0xef, 0x94, 0x02, 0xee, 0x94, 0x00, 0x50, 0x2a, 0x12,
  385. 0x42, 0xec, 0xef, 0x4e, 0x70, 0x23, 0x12, 0x43, 0x04, 0x60, 0x0a, 0x12,
  386. 0x43, 0x12, 0x70, 0x0c, 0x12, 0x43, 0x1f, 0x70, 0x07, 0x12, 0x46, 0x39,
  387. 0x7b, 0x03, 0x80, 0x07, 0x12, 0x46, 0x39, 0x12, 0x46, 0x43, 0xfb, 0x7a,
  388. 0x00, 0x7d, 0x54, 0x80, 0x3e, 0x12, 0x42, 0xec, 0xef, 0x4e, 0x70, 0x24,
  389. 0x12, 0x43, 0x04, 0x60, 0x0a, 0x12, 0x43, 0x12, 0x70, 0x0f, 0x12, 0x43,
  390. 0x1f, 0x70, 0x0a, 0x12, 0x46, 0x39, 0xe4, 0xfb, 0xfa, 0x7d, 0xee, 0x80,
  391. 0x1e, 0x12, 0x46, 0x39, 0x7b, 0x01, 0x7a, 0x00, 0x7d, 0xee, 0x80, 0x13,
  392. 0x12, 0x46, 0x39, 0x12, 0x46, 0x43, 0x54, 0x40, 0xfe, 0xc4, 0x13, 0x13,
  393. 0x54, 0x03, 0xfb, 0x7a, 0x00, 0x7d, 0xee, 0x12, 0x38, 0xbd, 0x7b, 0xff,
  394. 0x12, 0x43, 0x2c, 0xef, 0x4e, 0x70, 0x07, 0x74, 0x2a, 0x25, 0x19, 0xf8,
  395. 0xe4, 0xf6, 0x05, 0x19, 0xe5, 0x19, 0xc3, 0x94, 0x02, 0x50, 0x03, 0x02,
  396. 0x42, 0x15, 0x22, 0xe5, 0x19, 0x24, 0x17, 0xfd, 0x7b, 0x20, 0x7f, 0x04,
  397. 0x12, 0x3d, 0xd7, 0x22, 0xe5, 0x19, 0x24, 0x17, 0xfd, 0x7f, 0x04, 0x12,
  398. 0x3d, 0xd7, 0x22, 0x7b, 0x22, 0x7d, 0x18, 0x7f, 0x06, 0x12, 0x3d, 0xd7,
  399. 0xef, 0x64, 0x01, 0x4e, 0x22, 0x7d, 0x1c, 0xe4, 0xff, 0x12, 0x3e, 0x9a,
  400. 0xef, 0x54, 0x1b, 0x64, 0x0a, 0x22, 0x7b, 0xcc, 0x7d, 0x10, 0xff, 0x12,
  401. 0x3d, 0xd7, 0xef, 0x64, 0x01, 0x4e, 0x22, 0xe5, 0x19, 0x24, 0x17, 0xfd,
  402. 0x7f, 0x04, 0x12, 0x3d, 0xd7, 0x22, 0xd2, 0x08, 0x75, 0xfb, 0x03, 0xab,
  403. 0x7e, 0xaa, 0x7d, 0x7d, 0x19, 0x7f, 0x03, 0x12, 0x3e, 0xda, 0xe5, 0x7e,
  404. 0x54, 0x0f, 0x24, 0xf3, 0x60, 0x03, 0x02, 0x43, 0xe9, 0x12, 0x46, 0x5a,
  405. 0x12, 0x46, 0x61, 0xd8, 0xfb, 0xff, 0x20, 0xe2, 0x35, 0x13, 0x92, 0x0c,
  406. 0xef, 0xa2, 0xe1, 0x92, 0x0b, 0x30, 0x0c, 0x2a, 0xe4, 0xf5, 0x10, 0x7b,
  407. 0xfe, 0x12, 0x43, 0xff, 0xef, 0xc4, 0x33, 0x33, 0x54, 0xc0, 0xff, 0xc0,
  408. 0x07, 0x7b, 0x54, 0x12, 0x43, 0xff, 0xd0, 0xe0, 0x4f, 0xff, 0x74, 0x2a,
  409. 0x25, 0x10, 0xf8, 0xa6, 0x07, 0x05, 0x10, 0xe5, 0x10, 0xc3, 0x94, 0x02,
  410. 0x40, 0xd9, 0x12, 0x46, 0x5a, 0x12, 0x46, 0x61, 0xd8, 0xfb, 0x54, 0x05,
  411. 0x64, 0x04, 0x70, 0x27, 0x78, 0xc4, 0xe6, 0x78, 0xc6, 0xf6, 0xe5, 0x7d,
  412. 0xff, 0x33, 0x95, 0xe0, 0xef, 0x54, 0x0f, 0x78, 0xc4, 0xf6, 0x12, 0x44,
  413. 0x0a, 0x20, 0x0c, 0x0c, 0x12, 0x46, 0x5a, 0x12, 0x46, 0x61, 0xd8, 0xfb,
  414. 0x13, 0x92, 0x0d, 0x22, 0xc2, 0x0d, 0x22, 0x12, 0x46, 0x5a, 0x12, 0x46,
  415. 0x61, 0xd8, 0xfb, 0x54, 0x05, 0x64, 0x05, 0x70, 0x1e, 0x78, 0xc4, 0x7d,
  416. 0xb8, 0x12, 0x43, 0xf5, 0x78, 0xc1, 0x7d, 0x74, 0x12, 0x43, 0xf5, 0xe4,
  417. 0x78, 0xc1, 0xf6, 0x22, 0x7b, 0x01, 0x7a, 0x00, 0x7d, 0xee, 0x7f, 0x92,
  418. 0x12, 0x38, 0xbd, 0x22, 0xe6, 0xfb, 0x7a, 0x00, 0x7f, 0x92, 0x12, 0x38,
  419. 0xbd, 0x22, 0xe5, 0x10, 0x24, 0x17, 0xfd, 0x7f, 0x04, 0x12, 0x3d, 0xd7,
  420. 0x22, 0x78, 0xc1, 0xe6, 0xfb, 0x7a, 0x00, 0x7d, 0x74, 0x7f, 0x92, 0x12,
  421. 0x38, 0xbd, 0xe4, 0x78, 0xc1, 0xf6, 0xf5, 0x11, 0x74, 0x01, 0x7e, 0x00,
  422. 0xa8, 0x11, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9,
  423. 0xff, 0x78, 0xc4, 0xe6, 0xfd, 0xef, 0x5d, 0x60, 0x44, 0x85, 0x11, 0xfb,
  424. 0xe5, 0x11, 0x54, 0x02, 0x25, 0xe0, 0x25, 0xe0, 0xfe, 0xe4, 0x24, 0x5b,
  425. 0xfb, 0xee, 0x12, 0x45, 0xed, 0x12, 0x3e, 0xda, 0x7b, 0x40, 0x7d, 0x11,
  426. 0x7f, 0x07, 0x12, 0x3d, 0xd7, 0x74, 0xc7, 0x25, 0x11, 0xf8, 0xa6, 0x07,
  427. 0x7b, 0x11, 0x7d, 0x12, 0x7f, 0x07, 0x12, 0x3d, 0xd7, 0xef, 0x4e, 0x60,
  428. 0x09, 0x74, 0xe7, 0x25, 0x11, 0xf8, 0x76, 0x04, 0x80, 0x07, 0x74, 0xe7,
  429. 0x25, 0x11, 0xf8, 0x76, 0x0a, 0x05, 0x11, 0xe5, 0x11, 0xc3, 0x94, 0x04,
  430. 0x40, 0x9a, 0x78, 0xc6, 0xe6, 0x70, 0x15, 0x78, 0xc4, 0xe6, 0x60, 0x10,
  431. 0x75, 0xd9, 0x38, 0x75, 0xdb, 0x10, 0x7d, 0xfe, 0x12, 0x44, 0xb8, 0x7d,
  432. 0x76, 0x12, 0x44, 0xb8, 0x79, 0xc6, 0xe7, 0x78, 0xc4, 0x66, 0xff, 0x60,
  433. 0x03, 0x12, 0x40, 0x25, 0x78, 0xc4, 0xe6, 0x70, 0x09, 0xfb, 0xfa, 0x7d,
  434. 0xfe, 0x7f, 0x8e, 0x12, 0x38, 0xbd, 0x22, 0x7b, 0x01, 0x7a, 0x00, 0x7f,
  435. 0x8e, 0x12, 0x38, 0xbd, 0x22, 0xe4, 0xf5, 0xfb, 0x7d, 0x1c, 0xe4, 0xff,
  436. 0x12, 0x3e, 0x9a, 0xad, 0x07, 0xac, 0x06, 0xec, 0x54, 0xc0, 0xff, 0xed,
  437. 0x54, 0x3f, 0x4f, 0xf5, 0x20, 0x30, 0x06, 0x2c, 0x30, 0x01, 0x08, 0xa2,
  438. 0x04, 0x72, 0x03, 0x92, 0x07, 0x80, 0x21, 0x30, 0x04, 0x06, 0x7b, 0xcc,
  439. 0x7d, 0x11, 0x80, 0x0d, 0x30, 0x03, 0x06, 0x7b, 0xcc, 0x7d, 0x10, 0x80,
  440. 0x04, 0x7b, 0x66, 0x7d, 0x16, 0xe4, 0xff, 0x12, 0x3d, 0xd7, 0xee, 0x4f,
  441. 0x24, 0xff, 0x92, 0x07, 0xaf, 0xfb, 0x74, 0x26, 0x2f, 0xf8, 0xe6, 0xff,
  442. 0xa6, 0x20, 0x20, 0x07, 0x39, 0x8f, 0x20, 0x30, 0x07, 0x34, 0x30, 0x00,
  443. 0x31, 0x20, 0x04, 0x2e, 0x20, 0x03, 0x2b, 0xe4, 0xf5, 0xff, 0x75, 0xfc,
  444. 0xc2, 0xe5, 0xfc, 0x30, 0xe0, 0xfb, 0xaf, 0xfe, 0xef, 0x20, 0xe3, 0x1a,
  445. 0xae, 0xfd, 0x44, 0x08, 0xf5, 0xfe, 0x75, 0xfc, 0x80, 0xe5, 0xfc, 0x30,
  446. 0xe0, 0xfb, 0x8f, 0xfe, 0x8e, 0xfd, 0x75, 0xfc, 0x80, 0xe5, 0xfc, 0x30,
  447. 0xe0, 0xfb, 0x05, 0xfb, 0xaf, 0xfb, 0xef, 0xc3, 0x94, 0x04, 0x50, 0x03,
  448. 0x02, 0x44, 0xc5, 0xe4, 0xf5, 0xfb, 0x22, 0xe5, 0x7e, 0x54, 0x0f, 0x64,
  449. 0x01, 0x70, 0x23, 0xe5, 0x7e, 0x30, 0xe4, 0x1e, 0x90, 0x47, 0xd0, 0xe0,
  450. 0x44, 0x02, 0xf0, 0x54, 0xfb, 0xf0, 0x90, 0x47, 0xd4, 0xe0, 0x44, 0x04,
  451. 0xf0, 0x7b, 0x03, 0x7d, 0x5b, 0x7f, 0x5d, 0x12, 0x36, 0x29, 0x7b, 0x0e,
  452. 0x80, 0x1c, 0x90, 0x47, 0xd0, 0xe0, 0x54, 0xfd, 0xf0, 0x44, 0x04, 0xf0,
  453. 0x90, 0x47, 0xd4, 0xe0, 0x54, 0xfb, 0xf0, 0x7b, 0x02, 0x7d, 0x5b, 0x7f,
  454. 0x5d, 0x12, 0x36, 0x29, 0x7b, 0x06, 0x7d, 0x60, 0x7f, 0x63, 0x12, 0x36,
  455. 0x29, 0x22, 0xe5, 0x7e, 0x30, 0xe5, 0x35, 0x30, 0xe4, 0x0b, 0x7b, 0x02,
  456. 0x7d, 0x33, 0x7f, 0x35, 0x12, 0x36, 0x29, 0x80, 0x10, 0x7b, 0x01, 0x7d,
  457. 0x33, 0x7f, 0x35, 0x12, 0x36, 0x29, 0x90, 0x47, 0xd2, 0xe0, 0x44, 0x04,
  458. 0xf0, 0x90, 0x47, 0xd2, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x47, 0xd1, 0xe0,
  459. 0x44, 0x10, 0xf0, 0x7b, 0x05, 0x7d, 0x84, 0x7f, 0x86, 0x12, 0x36, 0x29,
  460. 0x22, 0xfb, 0xe5, 0x1c, 0x34, 0xf0, 0xfa, 0x7d, 0x10, 0x7f, 0x07, 0x22,
  461. 0x54, 0x01, 0xc4, 0x33, 0x54, 0xe0, 0xf5, 0xdb, 0x44, 0x08, 0xf5, 0xdb,
  462. 0x22, 0xf5, 0xdb, 0x75, 0xdb, 0x08, 0xf5, 0xdb, 0x75, 0xdb, 0x08, 0x22,
  463. 0xab, 0x07, 0xaa, 0x06, 0x7d, 0x10, 0x7f, 0x07, 0x12, 0x3e, 0xda, 0x7b,
  464. 0xff, 0x7d, 0x10, 0x7f, 0x07, 0x12, 0x3d, 0xd7, 0xef, 0x4e, 0x60, 0xf3,
  465. 0x22, 0x12, 0x44, 0xc2, 0x30, 0x0c, 0x03, 0x12, 0x42, 0x12, 0x78, 0xc4,
  466. 0xe6, 0xff, 0x60, 0x03, 0x12, 0x40, 0x25, 0x22, 0xe5, 0x19, 0x24, 0x17,
  467. 0x54, 0x1f, 0x44, 0x80, 0xff, 0x22, 0x74, 0x2a, 0x25, 0x19, 0xf8, 0xe6,
  468. 0x22, 0x12, 0x46, 0x72, 0x12, 0x46, 0x68, 0x90, 0x47, 0xfa, 0xe0, 0x54,
  469. 0xf8, 0x44, 0x02, 0xf0, 0x22, 0xe5, 0x7e, 0xae, 0x7d, 0x78, 0x04, 0x22,
  470. 0xce, 0xa2, 0xe7, 0x13, 0xce, 0x13, 0x22, 0xe4, 0x78, 0xc4, 0xf6, 0xc2,
  471. 0x0d, 0x78, 0xc1, 0xf6, 0x22, 0xc2, 0x0c, 0xc2, 0x0b, 0x22, 0x22,
  472. };
  473. static const u8 fw_patch_vsc8584[] = {
  474. 0xe8, 0x59, 0x02, 0xe8, 0x12, 0x02, 0xe8, 0x42, 0x02, 0xe8, 0x5a, 0x02,
  475. 0xe8, 0x5b, 0x02, 0xe8, 0x5c, 0xe5, 0x69, 0x54, 0x0f, 0x24, 0xf7, 0x60,
  476. 0x27, 0x24, 0xfc, 0x60, 0x23, 0x24, 0x08, 0x70, 0x14, 0xe5, 0x69, 0xae,
  477. 0x68, 0x78, 0x04, 0xce, 0xa2, 0xe7, 0x13, 0xce, 0x13, 0xd8, 0xf8, 0x7e,
  478. 0x00, 0x54, 0x0f, 0x80, 0x00, 0x7b, 0x01, 0x7a, 0x00, 0x7d, 0xee, 0x7f,
  479. 0x92, 0x12, 0x50, 0xee, 0x22, 0xe4, 0xf5, 0x10, 0x85, 0x10, 0xfb, 0x7d,
  480. 0x1c, 0xe4, 0xff, 0x12, 0x59, 0xea, 0x05, 0x10, 0xe5, 0x10, 0xc3, 0x94,
  481. 0x04, 0x40, 0xed, 0x22, 0x22, 0x22, 0x22, 0x22,
  482. };
  483. static int vsc8584_get_fw_crc(struct mii_dev *bus, int phy, u16 start,
  484. u16 *crc, const u8 *fw_patch, int fw_size)
  485. {
  486. int ret;
  487. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  488. MSCC_PHY_PAGE_EXT1);
  489. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_VERIPHY_CNTL_2, start);
  490. /* Add one byte to size for the one added by the patch_fw function */
  491. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_VERIPHY_CNTL_3,
  492. fw_size + 1);
  493. ret = vsc8584_cmd(bus, phy, PROC_CMD_CRC16);
  494. if (ret)
  495. goto out;
  496. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  497. MSCC_PHY_PAGE_EXT1);
  498. *crc = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_VERIPHY_CNTL_2);
  499. out:
  500. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  501. MSCC_PHY_PAGE_STD);
  502. return ret;
  503. }
  504. static int vsc8584_patch_fw(struct mii_dev *bus, int phy, const u8 *fw_patch,
  505. int fw_size)
  506. {
  507. int i, ret;
  508. ret = vsc8584_micro_assert_reset(bus, phy);
  509. if (ret) {
  510. pr_err("%s: failed to assert reset of micro\n", __func__);
  511. return ret;
  512. }
  513. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  514. MSCC_PHY_PAGE_GPIO);
  515. /*
  516. * Hold 8051 Micro in SW Reset, Enable auto incr address and patch clock
  517. * Disable the 8051 Micro clock
  518. */
  519. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS,
  520. RUN_FROM_INT_ROM | AUTOINC_ADDR | PATCH_RAM_CLK |
  521. MICRO_CLK_EN | MICRO_CLK_DIVIDE(2));
  522. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, READ_PRAM |
  523. INT_MEM_WRITE_EN | INT_MEM_DATA(2));
  524. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_ADDR, 0x0000);
  525. for (i = 0; i < fw_size; i++)
  526. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL,
  527. READ_PRAM | INT_MEM_WRITE_EN | fw_patch[i]);
  528. /* Clear internal memory access */
  529. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, READ_RAM);
  530. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  531. MSCC_PHY_PAGE_STD);
  532. return 0;
  533. }
  534. static bool vsc8574_is_serdes_init(struct mii_dev *bus, int phy)
  535. {
  536. u16 reg;
  537. bool ret;
  538. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  539. MSCC_PHY_PAGE_GPIO);
  540. reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_TRAP_ROM_ADDR(1));
  541. if (reg != MSCC_TRAP_ROM_ADDR_SERDES_INIT) {
  542. ret = false;
  543. goto out;
  544. }
  545. reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_PATCH_RAM_ADDR(1));
  546. if (reg != MSCC_PATCH_RAM_ADDR_SERDES_INIT) {
  547. ret = false;
  548. goto out;
  549. }
  550. reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL);
  551. if (reg != EN_PATCH_RAM_TRAP_ADDR(1)) {
  552. ret = false;
  553. goto out;
  554. }
  555. reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS);
  556. if ((MICRO_NSOFT_RESET | RUN_FROM_INT_ROM | DW8051_CLK_EN |
  557. MICRO_CLK_EN) != (reg & MSCC_DW8051_VLD_MASK)) {
  558. ret = false;
  559. goto out;
  560. }
  561. ret = true;
  562. out:
  563. bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  564. MSCC_PHY_PAGE_GPIO);
  565. return ret;
  566. }
  567. static int vsc8574_config_pre_init(struct phy_device *phydev)
  568. {
  569. struct mii_dev *bus = phydev->bus;
  570. u16 crc, reg, phy0, addr;
  571. bool serdes_init;
  572. int ret;
  573. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  574. MSCC_PHY_PAGE_EXT1);
  575. addr = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_4);
  576. addr >>= PHY_CNTL_4_ADDR_POS;
  577. reg = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_ACTIPHY_CNTL);
  578. if (reg & PHY_ADDR_REVERSED)
  579. phy0 = phydev->addr + addr;
  580. else
  581. phy0 = phydev->addr - addr;
  582. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  583. MSCC_PHY_PAGE_STD);
  584. /* all writes below are broadcasted to all PHYs in the same package */
  585. reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS);
  586. reg |= SMI_BROADCAST_WR_EN;
  587. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS, reg);
  588. /*
  589. * The below register writes are tweaking analog and electrical
  590. * configuration that were determined through characterization by PHY
  591. * engineers. These don't mean anything more than "these are the best
  592. * values".
  593. */
  594. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_2, 0x0040);
  595. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  596. MSCC_PHY_PAGE_TEST);
  597. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_20, 0x4320);
  598. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_24, 0x0c00);
  599. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_9, 0x18ca);
  600. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_5, 0x1b20);
  601. reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8);
  602. reg |= TR_CLK_DISABLE;
  603. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8, reg);
  604. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  605. MSCC_PHY_PAGE_TR);
  606. vsc8584_csr_write(bus, phy0, 0x0fae, 0x000401bd);
  607. vsc8584_csr_write(bus, phy0, 0x0fac, 0x000f000f);
  608. vsc8584_csr_write(bus, phy0, 0x17a0, 0x00a0f147);
  609. vsc8584_csr_write(bus, phy0, 0x0fe4, 0x00052f54);
  610. vsc8584_csr_write(bus, phy0, 0x1792, 0x0027303d);
  611. vsc8584_csr_write(bus, phy0, 0x07fe, 0x00000704);
  612. vsc8584_csr_write(bus, phy0, 0x0fe0, 0x00060150);
  613. vsc8584_csr_write(bus, phy0, 0x0f82, 0x0012b00a);
  614. vsc8584_csr_write(bus, phy0, 0x0f80, 0x00000d74);
  615. vsc8584_csr_write(bus, phy0, 0x02e0, 0x00000012);
  616. vsc8584_csr_write(bus, phy0, 0x03a2, 0x00050208);
  617. vsc8584_csr_write(bus, phy0, 0x03b2, 0x00009186);
  618. vsc8584_csr_write(bus, phy0, 0x0fb0, 0x000e3700);
  619. vsc8584_csr_write(bus, phy0, 0x1688, 0x00049f81);
  620. vsc8584_csr_write(bus, phy0, 0x0fd2, 0x0000ffff);
  621. vsc8584_csr_write(bus, phy0, 0x168a, 0x00039fa2);
  622. vsc8584_csr_write(bus, phy0, 0x1690, 0x0020640b);
  623. vsc8584_csr_write(bus, phy0, 0x0258, 0x00002220);
  624. vsc8584_csr_write(bus, phy0, 0x025a, 0x00002a20);
  625. vsc8584_csr_write(bus, phy0, 0x025c, 0x00003060);
  626. vsc8584_csr_write(bus, phy0, 0x025e, 0x00003fa0);
  627. vsc8584_csr_write(bus, phy0, 0x03a6, 0x0000e0f0);
  628. vsc8584_csr_write(bus, phy0, 0x0f92, 0x00001489);
  629. vsc8584_csr_write(bus, phy0, 0x16a2, 0x00007000);
  630. vsc8584_csr_write(bus, phy0, 0x16a6, 0x00071448);
  631. vsc8584_csr_write(bus, phy0, 0x16a0, 0x00eeffdd);
  632. vsc8584_csr_write(bus, phy0, 0x0fe8, 0x0091b06c);
  633. vsc8584_csr_write(bus, phy0, 0x0fea, 0x00041600);
  634. vsc8584_csr_write(bus, phy0, 0x16b0, 0x00eeff00);
  635. vsc8584_csr_write(bus, phy0, 0x16b2, 0x00007000);
  636. vsc8584_csr_write(bus, phy0, 0x16b4, 0x00000814);
  637. vsc8584_csr_write(bus, phy0, 0x0f90, 0x00688980);
  638. vsc8584_csr_write(bus, phy0, 0x03a4, 0x0000d8f0);
  639. vsc8584_csr_write(bus, phy0, 0x0fc0, 0x00000400);
  640. vsc8584_csr_write(bus, phy0, 0x07fa, 0x0050100f);
  641. vsc8584_csr_write(bus, phy0, 0x0796, 0x00000003);
  642. vsc8584_csr_write(bus, phy0, 0x07f8, 0x00c3ff98);
  643. vsc8584_csr_write(bus, phy0, 0x0fa4, 0x0018292a);
  644. vsc8584_csr_write(bus, phy0, 0x168c, 0x00d2c46f);
  645. vsc8584_csr_write(bus, phy0, 0x17a2, 0x00000620);
  646. vsc8584_csr_write(bus, phy0, 0x16a4, 0x0013132f);
  647. vsc8584_csr_write(bus, phy0, 0x16a8, 0x00000000);
  648. vsc8584_csr_write(bus, phy0, 0x0ffc, 0x00c0a028);
  649. vsc8584_csr_write(bus, phy0, 0x0fec, 0x00901c09);
  650. vsc8584_csr_write(bus, phy0, 0x0fee, 0x0004a6a1);
  651. vsc8584_csr_write(bus, phy0, 0x0ffe, 0x00b01807);
  652. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  653. MSCC_PHY_PAGE_EXT2);
  654. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
  655. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  656. MSCC_PHY_PAGE_TR);
  657. vsc8584_csr_write(bus, phy0, 0x0486, 0x0008a518);
  658. vsc8584_csr_write(bus, phy0, 0x0488, 0x006dc696);
  659. vsc8584_csr_write(bus, phy0, 0x048a, 0x00000912);
  660. vsc8584_csr_write(bus, phy0, 0x048e, 0x00000db6);
  661. vsc8584_csr_write(bus, phy0, 0x049c, 0x00596596);
  662. vsc8584_csr_write(bus, phy0, 0x049e, 0x00000514);
  663. vsc8584_csr_write(bus, phy0, 0x04a2, 0x00410280);
  664. vsc8584_csr_write(bus, phy0, 0x04a4, 0x00000000);
  665. vsc8584_csr_write(bus, phy0, 0x04a6, 0x00000000);
  666. vsc8584_csr_write(bus, phy0, 0x04a8, 0x00000000);
  667. vsc8584_csr_write(bus, phy0, 0x04aa, 0x00000000);
  668. vsc8584_csr_write(bus, phy0, 0x04ae, 0x007df7dd);
  669. vsc8584_csr_write(bus, phy0, 0x04b0, 0x006d95d4);
  670. vsc8584_csr_write(bus, phy0, 0x04b2, 0x00492410);
  671. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  672. MSCC_PHY_PAGE_TEST);
  673. reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8);
  674. reg &= ~TR_CLK_DISABLE;
  675. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8, reg);
  676. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  677. MSCC_PHY_PAGE_STD);
  678. /* end of write broadcasting */
  679. reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS);
  680. reg &= ~SMI_BROADCAST_WR_EN;
  681. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS, reg);
  682. ret = vsc8584_get_fw_crc(bus, phy0,
  683. MSCC_VSC8574_REVB_INT8051_FW_START_ADDR, &crc,
  684. fw_patch_vsc8574,
  685. ARRAY_SIZE(fw_patch_vsc8574));
  686. if (ret)
  687. goto out;
  688. if (crc == MSCC_VSC8574_REVB_INT8051_FW_CRC) {
  689. serdes_init = vsc8574_is_serdes_init(bus, phy0);
  690. if (!serdes_init) {
  691. ret = vsc8584_micro_assert_reset(bus, phy0);
  692. if (ret) {
  693. pr_err("failed to assert reset of micro\n");
  694. return ret;
  695. }
  696. }
  697. } else {
  698. pr_debug("FW CRC is not the expected one, patching FW\n");
  699. serdes_init = false;
  700. if (vsc8584_patch_fw(bus, phy0, fw_patch_vsc8574,
  701. ARRAY_SIZE(fw_patch_vsc8574)))
  702. pr_warn("failed to patch FW, expect non-optimal device\n");
  703. }
  704. if (!serdes_init) {
  705. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  706. MSCC_PHY_PAGE_GPIO);
  707. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_TRAP_ROM_ADDR(1),
  708. MSCC_TRAP_ROM_ADDR_SERDES_INIT);
  709. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PATCH_RAM_ADDR(1),
  710. MSCC_PATCH_RAM_ADDR_SERDES_INIT);
  711. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL,
  712. EN_PATCH_RAM_TRAP_ADDR(1));
  713. vsc8584_micro_deassert_reset(bus, phy0, false);
  714. ret = vsc8584_get_fw_crc(bus, phy0,
  715. MSCC_VSC8574_REVB_INT8051_FW_START_ADDR,
  716. &crc, fw_patch_vsc8574,
  717. ARRAY_SIZE(fw_patch_vsc8574));
  718. if (ret)
  719. goto out;
  720. if (crc != MSCC_VSC8574_REVB_INT8051_FW_CRC)
  721. pr_warn("FW CRC after patching is not the expected one, expect non-optimal device\n");
  722. }
  723. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  724. MSCC_PHY_PAGE_GPIO);
  725. ret = vsc8584_cmd(bus, phy0, PROC_CMD_1588_DEFAULT_INIT |
  726. PROC_CMD_PHY_INIT);
  727. out:
  728. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  729. MSCC_PHY_PAGE_STD);
  730. return ret;
  731. }
  732. static int vsc8584_config_pre_init(struct phy_device *phydev)
  733. {
  734. struct mii_dev *bus = phydev->bus;
  735. u16 reg, crc, phy0, addr;
  736. int ret;
  737. if ((phydev->phy_id & MSCC_DEV_REV_MASK) != VSC8584_REVB) {
  738. pr_warn("VSC8584 revA not officially supported, skipping firmware patching. Use at your own risk.\n");
  739. return 0;
  740. }
  741. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  742. MSCC_PHY_PAGE_EXT1);
  743. addr = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_4);
  744. addr >>= PHY_CNTL_4_ADDR_POS;
  745. reg = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_ACTIPHY_CNTL);
  746. if (reg & PHY_ADDR_REVERSED)
  747. phy0 = phydev->addr + addr;
  748. else
  749. phy0 = phydev->addr - addr;
  750. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  751. MSCC_PHY_PAGE_STD);
  752. /* all writes below are broadcasted to all PHYs in the same package */
  753. reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS);
  754. reg |= SMI_BROADCAST_WR_EN;
  755. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS, reg);
  756. /*
  757. * The below register writes are tweaking analog and electrical
  758. * configuration that were determined through characterization by PHY
  759. * engineers. These don't mean anything more than "these are the best
  760. * values".
  761. */
  762. reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_BYPASS_CONTROL);
  763. reg |= PARALLEL_DET_IGNORE_ADVERTISED;
  764. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_BYPASS_CONTROL, reg);
  765. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  766. MSCC_PHY_PAGE_EXT3);
  767. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_SERDES_TX_CRC_ERR_CNT,
  768. 0x2000);
  769. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  770. MSCC_PHY_PAGE_TEST);
  771. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_5, 0x1f20);
  772. reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8);
  773. reg |= TR_CLK_DISABLE;
  774. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8, reg);
  775. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  776. MSCC_PHY_PAGE_TR);
  777. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16, 0xafa4);
  778. reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18);
  779. reg &= ~0x007f;
  780. reg |= 0x0019;
  781. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18, reg);
  782. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16, 0x8fa4);
  783. vsc8584_csr_write(bus, phy0, 0x07fa, 0x0050100f);
  784. vsc8584_csr_write(bus, phy0, 0x1688, 0x00049f81);
  785. vsc8584_csr_write(bus, phy0, 0x0f90, 0x00688980);
  786. vsc8584_csr_write(bus, phy0, 0x03a4, 0x0000d8f0);
  787. vsc8584_csr_write(bus, phy0, 0x0fc0, 0x00000400);
  788. vsc8584_csr_write(bus, phy0, 0x0f82, 0x0012b002);
  789. vsc8584_csr_write(bus, phy0, 0x1686, 0x00000004);
  790. vsc8584_csr_write(bus, phy0, 0x168c, 0x00d2c46f);
  791. vsc8584_csr_write(bus, phy0, 0x17a2, 0x00000620);
  792. vsc8584_csr_write(bus, phy0, 0x16a0, 0x00eeffdd);
  793. vsc8584_csr_write(bus, phy0, 0x16a6, 0x00071448);
  794. vsc8584_csr_write(bus, phy0, 0x16a4, 0x0013132f);
  795. vsc8584_csr_write(bus, phy0, 0x16a8, 0x00000000);
  796. vsc8584_csr_write(bus, phy0, 0x0ffc, 0x00c0a028);
  797. vsc8584_csr_write(bus, phy0, 0x0fe8, 0x0091b06c);
  798. vsc8584_csr_write(bus, phy0, 0x0fea, 0x00041600);
  799. vsc8584_csr_write(bus, phy0, 0x0f80, 0x00fffaff);
  800. vsc8584_csr_write(bus, phy0, 0x0fec, 0x00901809);
  801. vsc8584_csr_write(bus, phy0, 0x0ffe, 0x00b01007);
  802. vsc8584_csr_write(bus, phy0, 0x16b0, 0x00eeff00);
  803. vsc8584_csr_write(bus, phy0, 0x16b2, 0x00007000);
  804. vsc8584_csr_write(bus, phy0, 0x16b4, 0x00000814);
  805. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  806. MSCC_PHY_PAGE_EXT2);
  807. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
  808. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  809. MSCC_PHY_PAGE_TR);
  810. vsc8584_csr_write(bus, phy0, 0x0486, 0x0008a518);
  811. vsc8584_csr_write(bus, phy0, 0x0488, 0x006dc696);
  812. vsc8584_csr_write(bus, phy0, 0x048a, 0x00000912);
  813. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  814. MSCC_PHY_PAGE_TEST);
  815. reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8);
  816. reg &= ~TR_CLK_DISABLE;
  817. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8, reg);
  818. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  819. MSCC_PHY_PAGE_STD);
  820. /* end of write broadcasting */
  821. reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS);
  822. reg &= ~SMI_BROADCAST_WR_EN;
  823. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS, reg);
  824. ret = vsc8584_get_fw_crc(bus, phy0,
  825. MSCC_VSC8584_REVB_INT8051_FW_START_ADDR, &crc,
  826. fw_patch_vsc8584,
  827. ARRAY_SIZE(fw_patch_vsc8584));
  828. if (ret)
  829. goto out;
  830. if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC) {
  831. debug("FW CRC is not the expected one, patching FW...\n");
  832. if (vsc8584_patch_fw(bus, phy0, fw_patch_vsc8584,
  833. ARRAY_SIZE(fw_patch_vsc8584)))
  834. pr_warn("failed to patch FW, expect non-optimal device\n");
  835. }
  836. vsc8584_micro_deassert_reset(bus, phy0, false);
  837. ret = vsc8584_get_fw_crc(bus, phy0,
  838. MSCC_VSC8584_REVB_INT8051_FW_START_ADDR, &crc,
  839. fw_patch_vsc8584,
  840. ARRAY_SIZE(fw_patch_vsc8584));
  841. if (ret)
  842. goto out;
  843. if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC)
  844. pr_warn("FW CRC after patching is not the expected one, expect non-optimal device\n");
  845. ret = vsc8584_micro_assert_reset(bus, phy0);
  846. if (ret)
  847. goto out;
  848. vsc8584_micro_deassert_reset(bus, phy0, true);
  849. out:
  850. bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  851. MSCC_PHY_PAGE_STD);
  852. return ret;
  853. }
  854. static int mscc_vsc8531_vsc8541_init_scripts(struct phy_device *phydev)
  855. {
  856. u16 reg_val;
  857. /* Set to Access Token Ring Registers */
  858. phy_write(phydev, MDIO_DEVAD_NONE,
  859. MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
  860. /* Update LinkDetectCtrl default to optimized values */
  861. /* Determined during Silicon Validation Testing */
  862. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
  863. (MSCC_PHY_TR_LINKDETCTRL_ADDR | MSCC_PHY_TR_16_READ));
  864. reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17);
  865. reg_val = bitfield_replace(reg_val, MSCC_PHY_TR_LINKDETCTRL_POS,
  866. MSCC_PHY_TR_LINKDETCTRL_WIDTH,
  867. MSCC_PHY_TR_LINKDETCTRL_VAL);
  868. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17, reg_val);
  869. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
  870. (MSCC_PHY_TR_LINKDETCTRL_ADDR | MSCC_PHY_TR_16_WRITE));
  871. /* Update VgaThresh100 defaults to optimized values */
  872. /* Determined during Silicon Validation Testing */
  873. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
  874. (MSCC_PHY_TR_VGATHRESH100_ADDR | MSCC_PHY_TR_16_READ));
  875. reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18);
  876. reg_val = bitfield_replace(reg_val, MSCC_PHY_TR_VGATHRESH100_POS,
  877. MSCC_PHY_TR_VGATHRESH100_WIDTH,
  878. MSCC_PHY_TR_VGATHRESH100_VAL);
  879. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18, reg_val);
  880. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
  881. (MSCC_PHY_TR_VGATHRESH100_ADDR | MSCC_PHY_TR_16_WRITE));
  882. /* Update VgaGain10 defaults to optimized values */
  883. /* Determined during Silicon Validation Testing */
  884. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
  885. (MSCC_PHY_TR_VGAGAIN10_ADDR | MSCC_PHY_TR_16_READ));
  886. reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18);
  887. reg_val = bitfield_replace(reg_val, MSCC_PHY_TR_VGAGAIN10_U_POS,
  888. MSCC_PHY_TR_VGAGAIN10_U_WIDTH,
  889. MSCC_PHY_TR_VGAGAIN10_U_VAL);
  890. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18, reg_val);
  891. reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17);
  892. reg_val = bitfield_replace(reg_val, MSCC_PHY_TR_VGAGAIN10_L_POS,
  893. MSCC_PHY_TR_VGAGAIN10_L_WIDTH,
  894. MSCC_PHY_TR_VGAGAIN10_L_VAL);
  895. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17, reg_val);
  896. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
  897. (MSCC_PHY_TR_VGAGAIN10_ADDR | MSCC_PHY_TR_16_WRITE));
  898. /* Set back to Access Standard Page Registers */
  899. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  900. MSCC_PHY_PAGE_STD);
  901. return 0;
  902. }
  903. static int mscc_parse_status(struct phy_device *phydev)
  904. {
  905. u16 speed;
  906. u16 mii_reg;
  907. mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_AUX_CNTRL_STAT_REG);
  908. if (mii_reg & MIIM_AUX_CNTRL_STAT_F_DUPLEX)
  909. phydev->duplex = DUPLEX_FULL;
  910. else
  911. phydev->duplex = DUPLEX_HALF;
  912. speed = mii_reg & MIIM_AUX_CNTRL_STAT_SPEED_MASK;
  913. speed = speed >> MIIM_AUX_CNTRL_STAT_SPEED_POS;
  914. switch (speed) {
  915. case MIIM_AUX_CNTRL_STAT_SPEED_1000M:
  916. phydev->speed = SPEED_1000;
  917. break;
  918. case MIIM_AUX_CNTRL_STAT_SPEED_100M:
  919. phydev->speed = SPEED_100;
  920. break;
  921. case MIIM_AUX_CNTRL_STAT_SPEED_10M:
  922. phydev->speed = SPEED_10;
  923. break;
  924. default:
  925. phydev->speed = SPEED_10;
  926. break;
  927. }
  928. return 0;
  929. }
  930. static int mscc_startup(struct phy_device *phydev)
  931. {
  932. int retval;
  933. retval = genphy_update_link(phydev);
  934. if (retval)
  935. return retval;
  936. return mscc_parse_status(phydev);
  937. }
  938. static int mscc_phy_soft_reset(struct phy_device *phydev)
  939. {
  940. int retval = 0;
  941. u16 timeout = MSCC_PHY_RESET_TIMEOUT;
  942. u16 reg_val = 0;
  943. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  944. MSCC_PHY_PAGE_STD);
  945. reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
  946. phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, (reg_val | BMCR_RESET));
  947. reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
  948. while ((reg_val & BMCR_RESET) && (timeout > 0)) {
  949. reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
  950. timeout--;
  951. udelay(1000); /* 1 ms */
  952. }
  953. if (timeout == 0) {
  954. printf("MSCC PHY Soft_Reset Error: mac i/f = 0x%x\n",
  955. phydev->interface);
  956. retval = -ETIME;
  957. }
  958. return retval;
  959. }
  960. static int vsc8531_vsc8541_mac_config(struct phy_device *phydev)
  961. {
  962. u16 reg_val = 0;
  963. u16 mac_if = 0;
  964. u16 rx_clk_out = 0;
  965. /* For VSC8530/31 the only MAC modes are RMII/RGMII. */
  966. /* For VSC8540/41 the only MAC modes are (G)MII and RMII/RGMII. */
  967. /* Setup MAC Configuration */
  968. switch (phydev->interface) {
  969. case PHY_INTERFACE_MODE_MII:
  970. case PHY_INTERFACE_MODE_GMII:
  971. /* Set Reg23.12:11=0 */
  972. mac_if = MAC_IF_SELECTION_GMII;
  973. /* Set Reg20E2.11=1 */
  974. rx_clk_out = RX_CLK_OUT_DISABLE;
  975. break;
  976. case PHY_INTERFACE_MODE_RMII:
  977. /* Set Reg23.12:11=1 */
  978. mac_if = MAC_IF_SELECTION_RMII;
  979. /* Set Reg20E2.11=0 */
  980. rx_clk_out = RX_CLK_OUT_NORMAL;
  981. break;
  982. case PHY_INTERFACE_MODE_RGMII_TXID:
  983. case PHY_INTERFACE_MODE_RGMII_RXID:
  984. case PHY_INTERFACE_MODE_RGMII_ID:
  985. case PHY_INTERFACE_MODE_RGMII:
  986. /* Set Reg23.12:11=2 */
  987. mac_if = MAC_IF_SELECTION_RGMII;
  988. /* Set Reg20E2.11=0 */
  989. rx_clk_out = RX_CLK_OUT_NORMAL;
  990. break;
  991. default:
  992. printf("MSCC PHY - INVALID MAC i/f Config: mac i/f = 0x%x\n",
  993. phydev->interface);
  994. return -EINVAL;
  995. }
  996. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  997. MSCC_PHY_PAGE_STD);
  998. reg_val = phy_read(phydev, MDIO_DEVAD_NONE,
  999. MSCC_PHY_EXT_PHY_CNTL_1_REG);
  1000. /* Set MAC i/f bits Reg23.12:11 */
  1001. reg_val = bitfield_replace(reg_val, MAC_IF_SELECTION_POS,
  1002. MAC_IF_SELECTION_WIDTH, mac_if);
  1003. /* Update Reg23.12:11 */
  1004. phy_write(phydev, MDIO_DEVAD_NONE,
  1005. MSCC_PHY_EXT_PHY_CNTL_1_REG, reg_val);
  1006. /* Setup ExtPg_2 Register Access */
  1007. phy_write(phydev, MDIO_DEVAD_NONE,
  1008. MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXT2);
  1009. /* Read Reg20E2 */
  1010. reg_val = phy_read(phydev, MDIO_DEVAD_NONE,
  1011. MSCC_PHY_RGMII_CNTL_REG);
  1012. reg_val = bitfield_replace(reg_val, RX_CLK_OUT_POS,
  1013. RX_CLK_OUT_WIDTH, rx_clk_out);
  1014. /* Update Reg20E2.11 */
  1015. phy_write(phydev, MDIO_DEVAD_NONE,
  1016. MSCC_PHY_RGMII_CNTL_REG, reg_val);
  1017. /* Before leaving - Change back to Std Page Register Access */
  1018. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  1019. MSCC_PHY_PAGE_STD);
  1020. return 0;
  1021. }
  1022. static int vsc8531_vsc8541_clkout_config(struct phy_device *phydev)
  1023. {
  1024. struct ofnode_phandle_args phandle_args;
  1025. u32 clkout_rate = 0;
  1026. u16 reg_val;
  1027. int retval;
  1028. retval = dev_read_phandle_with_args(phydev->dev, "phy-handle", NULL,
  1029. 0, 0, &phandle_args);
  1030. if (!retval)
  1031. clkout_rate = ofnode_read_u32_default(phandle_args.node,
  1032. "vsc8531,clk-out-frequency", 0);
  1033. switch (clkout_rate) {
  1034. case 0:
  1035. reg_val = 0;
  1036. break;
  1037. case 25000000:
  1038. reg_val = CLKOUT_FREQ_25M | CLKOUT_ENABLE;
  1039. break;
  1040. case 50000000:
  1041. reg_val = CLKOUT_FREQ_50M | CLKOUT_ENABLE;
  1042. break;
  1043. case 125000000:
  1044. reg_val = CLKOUT_FREQ_125M | CLKOUT_ENABLE;
  1045. break;
  1046. default:
  1047. printf("PHY 8530/31 invalid clkout rate %u\n",
  1048. clkout_rate);
  1049. return -EINVAL;
  1050. }
  1051. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  1052. MSCC_PHY_PAGE_GPIO);
  1053. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_CLKOUT_CNTL, reg_val);
  1054. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  1055. MSCC_PHY_PAGE_STD);
  1056. return 0;
  1057. }
  1058. static int vsc8531_vsc8541_clk_skew_config(struct phy_device *phydev)
  1059. {
  1060. enum vsc_phy_rgmii_skew rx_clk_skew = VSC_PHY_RGMII_DELAY_200_PS;
  1061. enum vsc_phy_rgmii_skew tx_clk_skew = VSC_PHY_RGMII_DELAY_200_PS;
  1062. u16 reg_val;
  1063. if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
  1064. phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
  1065. rx_clk_skew = VSC_PHY_RGMII_DELAY_2000_PS;
  1066. if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
  1067. phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
  1068. tx_clk_skew = VSC_PHY_RGMII_DELAY_2000_PS;
  1069. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  1070. MSCC_PHY_PAGE_EXT2);
  1071. reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG);
  1072. /* Reg20E2 - Update RGMII RX_Clk Skews. */
  1073. reg_val = bitfield_replace(reg_val, RGMII_RX_CLK_DELAY_POS,
  1074. RGMII_RX_CLK_DELAY_WIDTH, rx_clk_skew);
  1075. /* Reg20E2 - Update RGMII TX_Clk Skews. */
  1076. reg_val = bitfield_replace(reg_val, RGMII_TX_CLK_DELAY_POS,
  1077. RGMII_TX_CLK_DELAY_WIDTH, tx_clk_skew);
  1078. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG, reg_val);
  1079. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  1080. MSCC_PHY_PAGE_STD);
  1081. return 0;
  1082. }
  1083. static int vsc8531_config(struct phy_device *phydev)
  1084. {
  1085. int retval = -EINVAL;
  1086. u16 reg_val;
  1087. u16 rmii_clk_out;
  1088. enum vsc_phy_clk_slew edge_rate = VSC_PHY_CLK_SLEW_RATE_4;
  1089. /* For VSC8530/31 and VSC8540/41 the init scripts are the same */
  1090. mscc_vsc8531_vsc8541_init_scripts(phydev);
  1091. /* For VSC8530/31 the only MAC modes are RMII/RGMII. */
  1092. switch (phydev->interface) {
  1093. case PHY_INTERFACE_MODE_RMII:
  1094. case PHY_INTERFACE_MODE_RGMII:
  1095. case PHY_INTERFACE_MODE_RGMII_TXID:
  1096. case PHY_INTERFACE_MODE_RGMII_RXID:
  1097. case PHY_INTERFACE_MODE_RGMII_ID:
  1098. retval = vsc8531_vsc8541_mac_config(phydev);
  1099. if (retval != 0)
  1100. return retval;
  1101. retval = mscc_phy_soft_reset(phydev);
  1102. if (retval != 0)
  1103. return retval;
  1104. break;
  1105. default:
  1106. printf("PHY 8530/31 MAC i/f Config Error: mac i/f = 0x%x\n",
  1107. phydev->interface);
  1108. return -EINVAL;
  1109. }
  1110. /* Default RMII Clk Output to 0=OFF/1=ON */
  1111. rmii_clk_out = 0;
  1112. retval = vsc8531_vsc8541_clk_skew_config(phydev);
  1113. if (retval != 0)
  1114. return retval;
  1115. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  1116. MSCC_PHY_PAGE_EXT2);
  1117. reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL);
  1118. /* Reg27E2 - Update Clk Slew Rate. */
  1119. reg_val = bitfield_replace(reg_val, EDGE_RATE_CNTL_POS,
  1120. EDGE_RATE_CNTL_WIDTH, edge_rate);
  1121. /* Reg27E2 - Update RMII Clk Out. */
  1122. reg_val = bitfield_replace(reg_val, RMII_CLK_OUT_ENABLE_POS,
  1123. RMII_CLK_OUT_ENABLE_WIDTH, rmii_clk_out);
  1124. /* Update Reg27E2 */
  1125. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL, reg_val);
  1126. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  1127. MSCC_PHY_PAGE_STD);
  1128. /* Configure the clk output */
  1129. retval = vsc8531_vsc8541_clkout_config(phydev);
  1130. if (retval != 0)
  1131. return retval;
  1132. return genphy_config_aneg(phydev);
  1133. }
  1134. static int vsc8541_config(struct phy_device *phydev)
  1135. {
  1136. int retval = -EINVAL;
  1137. u16 reg_val;
  1138. u16 rmii_clk_out;
  1139. enum vsc_phy_clk_slew edge_rate = VSC_PHY_CLK_SLEW_RATE_4;
  1140. /* For VSC8530/31 and VSC8540/41 the init scripts are the same */
  1141. mscc_vsc8531_vsc8541_init_scripts(phydev);
  1142. /* For VSC8540/41 the only MAC modes are (G)MII and RMII/RGMII. */
  1143. switch (phydev->interface) {
  1144. case PHY_INTERFACE_MODE_MII:
  1145. case PHY_INTERFACE_MODE_GMII:
  1146. case PHY_INTERFACE_MODE_RMII:
  1147. case PHY_INTERFACE_MODE_RGMII:
  1148. retval = vsc8531_vsc8541_mac_config(phydev);
  1149. if (retval != 0)
  1150. return retval;
  1151. retval = mscc_phy_soft_reset(phydev);
  1152. if (retval != 0)
  1153. return retval;
  1154. break;
  1155. default:
  1156. printf("PHY 8541 MAC i/f config Error: mac i/f = 0x%x\n",
  1157. phydev->interface);
  1158. return -EINVAL;
  1159. }
  1160. /* Default RMII Clk Output to 0=OFF/1=ON */
  1161. rmii_clk_out = 0;
  1162. retval = vsc8531_vsc8541_clk_skew_config(phydev);
  1163. if (retval != 0)
  1164. return retval;
  1165. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  1166. MSCC_PHY_PAGE_EXT2);
  1167. reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL);
  1168. /* Reg27E2 - Update Clk Slew Rate. */
  1169. reg_val = bitfield_replace(reg_val, EDGE_RATE_CNTL_POS,
  1170. EDGE_RATE_CNTL_WIDTH, edge_rate);
  1171. /* Reg27E2 - Update RMII Clk Out. */
  1172. reg_val = bitfield_replace(reg_val, RMII_CLK_OUT_ENABLE_POS,
  1173. RMII_CLK_OUT_ENABLE_WIDTH, rmii_clk_out);
  1174. /* Update Reg27E2 */
  1175. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL, reg_val);
  1176. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  1177. MSCC_PHY_PAGE_STD);
  1178. /* Configure the clk output */
  1179. retval = vsc8531_vsc8541_clkout_config(phydev);
  1180. if (retval != 0)
  1181. return retval;
  1182. return genphy_config_aneg(phydev);
  1183. }
  1184. static int vsc8584_config_init(struct phy_device *phydev)
  1185. {
  1186. struct vsc85xx_priv *priv = phydev->priv;
  1187. int ret;
  1188. u16 addr;
  1189. u16 reg_val;
  1190. u16 val;
  1191. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  1192. MSCC_PHY_PAGE_EXT1);
  1193. addr = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_4);
  1194. addr >>= PHY_CNTL_4_ADDR_POS;
  1195. ret = priv->config_pre(phydev);
  1196. if (ret)
  1197. return ret;
  1198. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  1199. MSCC_PHY_PAGE_GPIO);
  1200. if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
  1201. val = MAC_CFG_QSGMII;
  1202. else
  1203. val = MAC_CFG_SGMII;
  1204. reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_MAC_CFG_FASTLINK);
  1205. reg_val &= ~MAC_CFG_MASK;
  1206. reg_val |= val;
  1207. ret = phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_MAC_CFG_FASTLINK,
  1208. reg_val);
  1209. if (ret)
  1210. return ret;
  1211. reg_val = PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_RST_CONF_PORT |
  1212. PROC_CMD_READ_MOD_WRITE_PORT;
  1213. if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
  1214. reg_val |= PROC_CMD_QSGMII_MAC;
  1215. else
  1216. reg_val |= PROC_CMD_SGMII_MAC;
  1217. ret = vsc8584_cmd(phydev->bus, phydev->addr, reg_val);
  1218. if (ret)
  1219. return ret;
  1220. mdelay(10);
  1221. /* Disable SerDes for 100Base-FX */
  1222. ret = vsc8584_cmd(phydev->bus, phydev->addr, PROC_CMD_FIBER_MEDIA_CONF |
  1223. PROC_CMD_FIBER_PORT(addr) | PROC_CMD_FIBER_DISABLE |
  1224. PROC_CMD_READ_MOD_WRITE_PORT |
  1225. PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_100BASE_FX);
  1226. if (ret)
  1227. return ret;
  1228. /* Disable SerDes for 1000Base-X */
  1229. ret = vsc8584_cmd(phydev->bus, phydev->addr, PROC_CMD_FIBER_MEDIA_CONF |
  1230. PROC_CMD_FIBER_PORT(addr) | PROC_CMD_FIBER_DISABLE |
  1231. PROC_CMD_READ_MOD_WRITE_PORT |
  1232. PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_1000BASE_X);
  1233. if (ret)
  1234. return ret;
  1235. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  1236. MSCC_PHY_PAGE_STD);
  1237. reg_val = phy_read(phydev, MDIO_DEVAD_NONE,
  1238. MSCC_PHY_EXT_PHY_CNTL_1_REG);
  1239. reg_val &= ~(MEDIA_OP_MODE_MASK | VSC8584_MAC_IF_SELECTION_MASK);
  1240. reg_val |= MEDIA_OP_MODE_COPPER |
  1241. (VSC8584_MAC_IF_SELECTION_SGMII <<
  1242. VSC8584_MAC_IF_SELECTION_POS);
  1243. ret = phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_1_REG,
  1244. reg_val);
  1245. ret = mscc_phy_soft_reset(phydev);
  1246. if (ret != 0)
  1247. return ret;
  1248. return genphy_config(phydev);
  1249. }
  1250. static struct vsc85xx_priv vsc8574_priv = {
  1251. .config_pre = vsc8574_config_pre_init,
  1252. };
  1253. static int vsc8574_config(struct phy_device *phydev)
  1254. {
  1255. phydev->priv = &vsc8574_priv;
  1256. return vsc8584_config_init(phydev);
  1257. }
  1258. static struct vsc85xx_priv vsc8584_priv = {
  1259. .config_pre = vsc8584_config_pre_init,
  1260. };
  1261. static int vsc8584_config(struct phy_device *phydev)
  1262. {
  1263. phydev->priv = &vsc8584_priv;
  1264. return vsc8584_config_init(phydev);
  1265. }
  1266. static int vsc8502_config(struct phy_device *phydev)
  1267. {
  1268. bool rgmii_rx_delay = false, rgmii_tx_delay = false;
  1269. u16 reg = 0;
  1270. int ret;
  1271. /* Assume nothing needs to be done for the default GMII/MII mode */
  1272. if (!phy_interface_is_rgmii(phydev))
  1273. return 0;
  1274. /* Set Extended PHY Control 1 register to RGMII */
  1275. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_1_REG,
  1276. BIT(13) | BIT(12));
  1277. /* Soft reset required after changing PHY mode from the default
  1278. * of GMII/MII
  1279. */
  1280. ret = mscc_phy_soft_reset(phydev);
  1281. if (ret)
  1282. return ret;
  1283. if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
  1284. phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
  1285. rgmii_rx_delay = true;
  1286. if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
  1287. phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
  1288. rgmii_tx_delay = true;
  1289. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  1290. MSCC_PHY_PAGE_EXT2);
  1291. if (rgmii_rx_delay)
  1292. reg |= VSC_PHY_RGMII_DELAY_2000_PS << RGMII_RX_CLK_DELAY_POS;
  1293. if (rgmii_tx_delay)
  1294. reg |= VSC_PHY_RGMII_DELAY_2000_PS << RGMII_TX_CLK_DELAY_POS;
  1295. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG, reg);
  1296. phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
  1297. MSCC_PHY_PAGE_STD);
  1298. return 0;
  1299. }
  1300. U_BOOT_PHY_DRIVER(vsc8530) = {
  1301. .name = "Microsemi VSC8530",
  1302. .uid = PHY_ID_VSC8530,
  1303. .mask = 0x000ffff0,
  1304. .features = PHY_BASIC_FEATURES,
  1305. .config = &vsc8531_config,
  1306. .startup = &mscc_startup,
  1307. .shutdown = &genphy_shutdown,
  1308. };
  1309. U_BOOT_PHY_DRIVER(vsc8531) = {
  1310. .name = "Microsemi VSC8531",
  1311. .uid = PHY_ID_VSC8531,
  1312. .mask = 0x000ffff0,
  1313. .features = PHY_GBIT_FEATURES,
  1314. .config = &vsc8531_config,
  1315. .startup = &mscc_startup,
  1316. .shutdown = &genphy_shutdown,
  1317. };
  1318. U_BOOT_PHY_DRIVER(vsc8502) = {
  1319. .name = "Microsemi VSC8502",
  1320. .uid = PHY_ID_VSC8502,
  1321. .mask = 0x000ffff0,
  1322. .features = PHY_GBIT_FEATURES,
  1323. .config = &vsc8502_config,
  1324. .startup = &mscc_startup,
  1325. .shutdown = &genphy_shutdown,
  1326. };
  1327. U_BOOT_PHY_DRIVER(vsc8540) = {
  1328. .name = "Microsemi VSC8540",
  1329. .uid = PHY_ID_VSC8540,
  1330. .mask = 0x000ffff0,
  1331. .features = PHY_BASIC_FEATURES,
  1332. .config = &vsc8541_config,
  1333. .startup = &mscc_startup,
  1334. .shutdown = &genphy_shutdown,
  1335. };
  1336. U_BOOT_PHY_DRIVER(vsc8541) = {
  1337. .name = "Microsemi VSC8541",
  1338. .uid = PHY_ID_VSC8541,
  1339. .mask = 0x000ffff0,
  1340. .features = PHY_GBIT_FEATURES,
  1341. .config = &vsc8541_config,
  1342. .startup = &mscc_startup,
  1343. .shutdown = &genphy_shutdown,
  1344. };
  1345. U_BOOT_PHY_DRIVER(vsc8574) = {
  1346. .name = "Microsemi VSC8574",
  1347. .uid = PHY_ID_VSC8574,
  1348. .mask = 0x000ffff0,
  1349. .features = PHY_GBIT_FEATURES,
  1350. .config = &vsc8574_config,
  1351. .startup = &mscc_startup,
  1352. .shutdown = &genphy_shutdown,
  1353. };
  1354. U_BOOT_PHY_DRIVER(vsc8584) = {
  1355. .name = "Microsemi VSC8584",
  1356. .uid = PHY_ID_VSC8584,
  1357. .mask = 0x000ffff0,
  1358. .features = PHY_GBIT_FEATURES,
  1359. .config = &vsc8584_config,
  1360. .startup = &mscc_startup,
  1361. .shutdown = &genphy_shutdown,
  1362. };