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