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