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