net: phy: mscc: factorize part of config function for VSC8584
[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 struct vsc85xx_priv {
255         int (*config_pre)(struct phy_device *phydev);
256 };
257
258 static void vsc8584_csr_write(struct mii_dev *bus, int phy0, u16 addr, u32 val)
259 {
260         bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18,
261                    val >> 16);
262         bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17,
263                    val & GENMASK(15, 0));
264         bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
265                    MSCC_PHY_TR_16_WRITE | addr);
266 }
267
268 static int vsc8584_cmd(struct mii_dev *bus, int phy, u16 val)
269 {
270         unsigned long deadline;
271         u16 reg_val;
272
273         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
274                    MSCC_PHY_PAGE_GPIO);
275
276         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_PROC_CMD,
277                    PROC_CMD_NCOMPLETED | val);
278
279         deadline = timer_get_us() + PROC_CMD_NCOMPLETED_TIMEOUT_MS * 1000;
280         do {
281                 reg_val = bus->read(bus, phy, MDIO_DEVAD_NONE,
282                                     MSCC_PHY_PROC_CMD);
283         } while (timer_get_us() <= deadline &&
284                  (reg_val & PROC_CMD_NCOMPLETED) &&
285                  !(reg_val & PROC_CMD_FAILED));
286
287         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
288                    MSCC_PHY_PAGE_STD);
289
290         if (reg_val & PROC_CMD_FAILED)
291                 return -EIO;
292         if (reg_val & PROC_CMD_NCOMPLETED)
293                 return -ETIMEDOUT;
294
295         return 0;
296 }
297
298 static int vsc8584_micro_deassert_reset(struct mii_dev *bus, int phy,
299                                         bool patch_en)
300 {
301         u32 enable, release;
302
303         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
304                    MSCC_PHY_PAGE_GPIO);
305
306         enable = RUN_FROM_INT_ROM | MICRO_CLK_EN | DW8051_CLK_EN;
307         release = MICRO_NSOFT_RESET | RUN_FROM_INT_ROM | DW8051_CLK_EN |
308                 MICRO_CLK_EN;
309
310         if (patch_en) {
311                 enable |= MICRO_PATCH_EN;
312                 release |= MICRO_PATCH_EN;
313
314                 /* Clear all patches */
315                 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL,
316                            READ_RAM);
317         }
318
319         /*
320          * Enable 8051 Micro clock; CLEAR/SET patch present; disable PRAM clock
321          * override and addr. auto-incr; operate at 125 MHz
322          */
323         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS, enable);
324         /* Release 8051 Micro SW reset */
325         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS, release);
326
327         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
328                    MSCC_PHY_PAGE_STD);
329
330         return 0;
331 }
332
333 static int vsc8584_micro_assert_reset(struct mii_dev *bus, int phy)
334 {
335         int ret;
336         u16 reg;
337
338         ret = vsc8584_cmd(bus, phy, PROC_CMD_NOP);
339         if (ret)
340                 return ret;
341
342         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
343                    MSCC_PHY_PAGE_GPIO);
344
345         reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL);
346         reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
347         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, reg);
348
349         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_TRAP_ROM_ADDR(4), 0x005b);
350         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PATCH_RAM_ADDR(4), 0x005b);
351
352         reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL);
353         reg |= EN_PATCH_RAM_TRAP_ADDR(4);
354         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, reg);
355
356         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_PROC_CMD, PROC_CMD_NOP);
357
358         reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS);
359         reg &= ~MICRO_NSOFT_RESET;
360         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS, reg);
361
362         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_PROC_CMD,
363                    PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_SGMII_PORT(0) |
364                    PROC_CMD_NO_MAC_CONF | PROC_CMD_READ);
365
366         reg = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL);
367         reg &= ~EN_PATCH_RAM_TRAP_ADDR(4);
368         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, reg);
369
370         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
371                    MSCC_PHY_PAGE_STD);
372
373         return 0;
374 }
375
376 static const u8 fw_patch_vsc8584[] = {
377         0xe8, 0x59, 0x02, 0xe8, 0x12, 0x02, 0xe8, 0x42, 0x02, 0xe8, 0x5a, 0x02,
378         0xe8, 0x5b, 0x02, 0xe8, 0x5c, 0xe5, 0x69, 0x54, 0x0f, 0x24, 0xf7, 0x60,
379         0x27, 0x24, 0xfc, 0x60, 0x23, 0x24, 0x08, 0x70, 0x14, 0xe5, 0x69, 0xae,
380         0x68, 0x78, 0x04, 0xce, 0xa2, 0xe7, 0x13, 0xce, 0x13, 0xd8, 0xf8, 0x7e,
381         0x00, 0x54, 0x0f, 0x80, 0x00, 0x7b, 0x01, 0x7a, 0x00, 0x7d, 0xee, 0x7f,
382         0x92, 0x12, 0x50, 0xee, 0x22, 0xe4, 0xf5, 0x10, 0x85, 0x10, 0xfb, 0x7d,
383         0x1c, 0xe4, 0xff, 0x12, 0x59, 0xea, 0x05, 0x10, 0xe5, 0x10, 0xc3, 0x94,
384         0x04, 0x40, 0xed, 0x22, 0x22, 0x22, 0x22, 0x22,
385 };
386
387 static int vsc8584_get_fw_crc(struct mii_dev *bus, int phy, u16 start,
388                               u16 *crc, const u8 *fw_patch, int fw_size)
389 {
390         int ret;
391
392         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
393                    MSCC_PHY_PAGE_EXT1);
394
395         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_VERIPHY_CNTL_2, start);
396         /* Add one byte to size for the one added by the patch_fw function */
397         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_VERIPHY_CNTL_3,
398                    fw_size + 1);
399
400         ret = vsc8584_cmd(bus, phy, PROC_CMD_CRC16);
401         if (ret)
402                 goto out;
403
404         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
405                    MSCC_PHY_PAGE_EXT1);
406
407         *crc = bus->read(bus, phy, MDIO_DEVAD_NONE, MSCC_PHY_VERIPHY_CNTL_2);
408
409 out:
410         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
411                    MSCC_PHY_PAGE_STD);
412
413         return ret;
414 }
415
416 static int vsc8584_patch_fw(struct mii_dev *bus, int phy, const u8 *fw_patch,
417                             int fw_size)
418 {
419         int i, ret;
420
421         ret = vsc8584_micro_assert_reset(bus, phy);
422         if (ret) {
423                 pr_err("%s: failed to assert reset of micro\n", __func__);
424                 return ret;
425         }
426
427         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
428                    MSCC_PHY_PAGE_GPIO);
429
430         /*
431          * Hold 8051 Micro in SW Reset, Enable auto incr address and patch clock
432          * Disable the 8051 Micro clock
433          */
434         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_DW8051_CNTL_STATUS,
435                    RUN_FROM_INT_ROM | AUTOINC_ADDR | PATCH_RAM_CLK |
436                    MICRO_CLK_EN | MICRO_CLK_DIVIDE(2));
437         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, READ_PRAM |
438                    INT_MEM_WRITE_EN | INT_MEM_DATA(2));
439         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_ADDR, 0x0000);
440
441         for (i = 0; i < fw_size; i++)
442                 bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL,
443                            READ_PRAM | INT_MEM_WRITE_EN | fw_patch[i]);
444
445         /* Clear internal memory access */
446         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_INT_MEM_CNTL, READ_RAM);
447
448         bus->write(bus, phy, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
449                    MSCC_PHY_PAGE_STD);
450
451         return 0;
452 }
453
454 static int vsc8584_config_pre_init(struct phy_device *phydev)
455 {
456         struct mii_dev *bus = phydev->bus;
457         u16 reg, crc, phy0, addr;
458         int ret;
459
460         if ((phydev->phy_id & MSCC_DEV_REV_MASK) != VSC8584_REVB) {
461                 pr_warn("VSC8584 revA not officially supported, skipping firmware patching. Use at your own risk.\n");
462                 return 0;
463         }
464
465         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
466                   MSCC_PHY_PAGE_EXT1);
467         addr = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_4);
468         addr >>= PHY_CNTL_4_ADDR_POS;
469
470         reg = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_ACTIPHY_CNTL);
471         if (reg & PHY_ADDR_REVERSED)
472                 phy0 = phydev->addr + addr;
473         else
474                 phy0 = phydev->addr - addr;
475
476         bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
477                    MSCC_PHY_PAGE_STD);
478
479         /* all writes below are broadcasted to all PHYs in the same package */
480         reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS);
481         reg |= SMI_BROADCAST_WR_EN;
482         bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS, reg);
483
484         /*
485          * The below register writes are tweaking analog and electrical
486          * configuration that were determined through characterization by PHY
487          * engineers. These don't mean anything more than "these are the best
488          * values".
489          */
490         reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_BYPASS_CONTROL);
491         reg |= PARALLEL_DET_IGNORE_ADVERTISED;
492         bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_BYPASS_CONTROL, reg);
493
494         bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
495                    MSCC_PHY_PAGE_EXT3);
496
497         bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_SERDES_TX_CRC_ERR_CNT,
498                    0x2000);
499
500         bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
501                    MSCC_PHY_PAGE_TEST);
502
503         bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_5, 0x1f20);
504
505         reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8);
506         reg |= TR_CLK_DISABLE;
507         bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8, reg);
508
509         bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
510                    MSCC_PHY_PAGE_TR);
511
512         bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16, 0xafa4);
513
514         reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18);
515         reg &= ~0x007f;
516         reg |= 0x0019;
517         bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18, reg);
518
519         bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16, 0x8fa4);
520
521         vsc8584_csr_write(bus, phy0, 0x07fa, 0x0050100f);
522         vsc8584_csr_write(bus, phy0, 0x1688, 0x00049f81);
523         vsc8584_csr_write(bus, phy0, 0x0f90, 0x00688980);
524         vsc8584_csr_write(bus, phy0, 0x03a4, 0x0000d8f0);
525         vsc8584_csr_write(bus, phy0, 0x0fc0, 0x00000400);
526         vsc8584_csr_write(bus, phy0, 0x0f82, 0x0012b002);
527         vsc8584_csr_write(bus, phy0, 0x1686, 0x00000004);
528         vsc8584_csr_write(bus, phy0, 0x168c, 0x00d2c46f);
529         vsc8584_csr_write(bus, phy0, 0x17a2, 0x00000620);
530         vsc8584_csr_write(bus, phy0, 0x16a0, 0x00eeffdd);
531         vsc8584_csr_write(bus, phy0, 0x16a6, 0x00071448);
532         vsc8584_csr_write(bus, phy0, 0x16a4, 0x0013132f);
533         vsc8584_csr_write(bus, phy0, 0x16a8, 0x00000000);
534         vsc8584_csr_write(bus, phy0, 0x0ffc, 0x00c0a028);
535         vsc8584_csr_write(bus, phy0, 0x0fe8, 0x0091b06c);
536         vsc8584_csr_write(bus, phy0, 0x0fea, 0x00041600);
537         vsc8584_csr_write(bus, phy0, 0x0f80, 0x00fffaff);
538         vsc8584_csr_write(bus, phy0, 0x0fec, 0x00901809);
539         vsc8584_csr_write(bus, phy0, 0x0ffe, 0x00b01007);
540         vsc8584_csr_write(bus, phy0, 0x16b0, 0x00eeff00);
541         vsc8584_csr_write(bus, phy0, 0x16b2, 0x00007000);
542         vsc8584_csr_write(bus, phy0, 0x16b4, 0x00000814);
543
544         bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
545                    MSCC_PHY_PAGE_EXT2);
546
547         bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_CU_PMD_TX_CNTL, 0x028e);
548
549         bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
550                    MSCC_PHY_PAGE_TR);
551
552         vsc8584_csr_write(bus, phy0, 0x0486, 0x0008a518);
553         vsc8584_csr_write(bus, phy0, 0x0488, 0x006dc696);
554         vsc8584_csr_write(bus, phy0, 0x048a, 0x00000912);
555
556         bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
557                    MSCC_PHY_PAGE_TEST);
558
559         reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8);
560         reg &= ~TR_CLK_DISABLE;
561         bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_TEST_PAGE_8, reg);
562
563         bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
564                    MSCC_PHY_PAGE_STD);
565
566         /* end of write broadcasting */
567         reg = bus->read(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS);
568         reg &= ~SMI_BROADCAST_WR_EN;
569         bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_PHY_EXT_CNTL_STATUS, reg);
570
571         ret = vsc8584_get_fw_crc(bus, phy0,
572                                  MSCC_VSC8584_REVB_INT8051_FW_START_ADDR, &crc,
573                                  fw_patch_vsc8584,
574                                  ARRAY_SIZE(fw_patch_vsc8584));
575         if (ret)
576                 goto out;
577
578         if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC) {
579                 debug("FW CRC is not the expected one, patching FW...\n");
580                 if (vsc8584_patch_fw(bus, phy0, fw_patch_vsc8584,
581                                      ARRAY_SIZE(fw_patch_vsc8584)))
582                         pr_warn("failed to patch FW, expect non-optimal device\n");
583         }
584
585         vsc8584_micro_deassert_reset(bus, phy0, false);
586
587         ret = vsc8584_get_fw_crc(bus, phy0,
588                                  MSCC_VSC8584_REVB_INT8051_FW_START_ADDR, &crc,
589                                  fw_patch_vsc8584,
590                                  ARRAY_SIZE(fw_patch_vsc8584));
591         if (ret)
592                 goto out;
593
594         if (crc != MSCC_VSC8584_REVB_INT8051_FW_CRC)
595                 pr_warn("FW CRC after patching is not the expected one, expect non-optimal device\n");
596
597         ret = vsc8584_micro_assert_reset(bus, phy0);
598         if (ret)
599                 goto out;
600
601         vsc8584_micro_deassert_reset(bus, phy0, true);
602
603 out:
604         bus->write(bus, phy0, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
605                    MSCC_PHY_PAGE_STD);
606
607         return ret;
608 }
609
610 static int mscc_vsc8531_vsc8541_init_scripts(struct phy_device *phydev)
611 {
612         u16     reg_val;
613
614         /* Set to Access Token Ring Registers */
615         phy_write(phydev, MDIO_DEVAD_NONE,
616                   MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
617
618         /* Update LinkDetectCtrl default to optimized values */
619         /* Determined during Silicon Validation Testing */
620         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
621                   (MSCC_PHY_TR_LINKDETCTRL_ADDR | MSCC_PHY_TR_16_READ));
622         reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17);
623         reg_val = bitfield_replace(reg_val, MSCC_PHY_TR_LINKDETCTRL_POS,
624                                    MSCC_PHY_TR_LINKDETCTRL_WIDTH,
625                                    MSCC_PHY_TR_LINKDETCTRL_VAL);
626
627         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17, reg_val);
628         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
629                   (MSCC_PHY_TR_LINKDETCTRL_ADDR | MSCC_PHY_TR_16_WRITE));
630
631         /* Update VgaThresh100 defaults to optimized values */
632         /* Determined during Silicon Validation Testing */
633         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
634                   (MSCC_PHY_TR_VGATHRESH100_ADDR | MSCC_PHY_TR_16_READ));
635
636         reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18);
637         reg_val = bitfield_replace(reg_val, MSCC_PHY_TR_VGATHRESH100_POS,
638                                    MSCC_PHY_TR_VGATHRESH100_WIDTH,
639                                    MSCC_PHY_TR_VGATHRESH100_VAL);
640
641         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18, reg_val);
642         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
643                   (MSCC_PHY_TR_VGATHRESH100_ADDR | MSCC_PHY_TR_16_WRITE));
644
645         /* Update VgaGain10 defaults to optimized values */
646         /* Determined during Silicon Validation Testing */
647         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
648                   (MSCC_PHY_TR_VGAGAIN10_ADDR | MSCC_PHY_TR_16_READ));
649
650         reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18);
651         reg_val = bitfield_replace(reg_val, MSCC_PHY_TR_VGAGAIN10_U_POS,
652                                    MSCC_PHY_TR_VGAGAIN10_U_WIDTH,
653                                    MSCC_PHY_TR_VGAGAIN10_U_VAL);
654
655         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18, reg_val);
656         reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17);
657         reg_val = bitfield_replace(reg_val, MSCC_PHY_TR_VGAGAIN10_L_POS,
658                                    MSCC_PHY_TR_VGAGAIN10_L_WIDTH,
659                                    MSCC_PHY_TR_VGAGAIN10_L_VAL);
660
661         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17, reg_val);
662         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
663                   (MSCC_PHY_TR_VGAGAIN10_ADDR | MSCC_PHY_TR_16_WRITE));
664
665         /* Set back to Access Standard Page Registers */
666         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
667                   MSCC_PHY_PAGE_STD);
668
669         return 0;
670 }
671
672 static int mscc_parse_status(struct phy_device *phydev)
673 {
674         u16 speed;
675         u16 mii_reg;
676
677         mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_AUX_CNTRL_STAT_REG);
678
679         if (mii_reg & MIIM_AUX_CNTRL_STAT_F_DUPLEX)
680                 phydev->duplex = DUPLEX_FULL;
681         else
682                 phydev->duplex = DUPLEX_HALF;
683
684         speed = mii_reg & MIIM_AUX_CNTRL_STAT_SPEED_MASK;
685         speed = speed >> MIIM_AUX_CNTRL_STAT_SPEED_POS;
686
687         switch (speed) {
688         case MIIM_AUX_CNTRL_STAT_SPEED_1000M:
689                 phydev->speed = SPEED_1000;
690                 break;
691         case MIIM_AUX_CNTRL_STAT_SPEED_100M:
692                 phydev->speed = SPEED_100;
693                 break;
694         case MIIM_AUX_CNTRL_STAT_SPEED_10M:
695                 phydev->speed = SPEED_10;
696                 break;
697         default:
698                 phydev->speed = SPEED_10;
699                 break;
700         }
701
702         return 0;
703 }
704
705 static int mscc_startup(struct phy_device *phydev)
706 {
707         int retval;
708
709         retval = genphy_update_link(phydev);
710
711         if (retval)
712                 return retval;
713
714         return mscc_parse_status(phydev);
715 }
716
717 static int mscc_phy_soft_reset(struct phy_device *phydev)
718 {
719         int     retval = 0;
720         u16     timeout = MSCC_PHY_RESET_TIMEOUT;
721         u16     reg_val = 0;
722
723         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
724                   MSCC_PHY_PAGE_STD);
725
726         reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
727         phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, (reg_val | BMCR_RESET));
728
729         reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
730
731         while ((reg_val & BMCR_RESET) && (timeout > 0)) {
732                 reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
733                 timeout--;
734                 udelay(1000);   /* 1 ms */
735         }
736
737         if (timeout == 0) {
738                 printf("MSCC PHY Soft_Reset Error: mac i/f = 0x%x\n",
739                        phydev->interface);
740                 retval = -ETIME;
741         }
742
743         return retval;
744 }
745
746 static int vsc8531_vsc8541_mac_config(struct phy_device *phydev)
747 {
748         u16     reg_val = 0;
749         u16     mac_if = 0;
750         u16     rx_clk_out = 0;
751
752         /* For VSC8530/31 the only MAC modes are RMII/RGMII. */
753         /* For VSC8540/41 the only MAC modes are (G)MII and RMII/RGMII. */
754         /* Setup MAC Configuration */
755         switch (phydev->interface) {
756         case PHY_INTERFACE_MODE_MII:
757         case PHY_INTERFACE_MODE_GMII:
758                 /* Set Reg23.12:11=0 */
759                 mac_if = MAC_IF_SELECTION_GMII;
760                 /* Set Reg20E2.11=1 */
761                 rx_clk_out = RX_CLK_OUT_DISABLE;
762                 break;
763
764         case PHY_INTERFACE_MODE_RMII:
765                 /* Set Reg23.12:11=1 */
766                 mac_if = MAC_IF_SELECTION_RMII;
767                 /* Set Reg20E2.11=0 */
768                 rx_clk_out = RX_CLK_OUT_NORMAL;
769                 break;
770
771         case PHY_INTERFACE_MODE_RGMII:
772                 /* Set Reg23.12:11=2 */
773                 mac_if = MAC_IF_SELECTION_RGMII;
774                 /* Set Reg20E2.11=0 */
775                 rx_clk_out = RX_CLK_OUT_NORMAL;
776                 break;
777
778         default:
779                 printf("MSCC PHY - INVALID MAC i/f Config: mac i/f = 0x%x\n",
780                        phydev->interface);
781                 return -EINVAL;
782         }
783
784         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
785                   MSCC_PHY_PAGE_STD);
786
787         reg_val = phy_read(phydev, MDIO_DEVAD_NONE,
788                            MSCC_PHY_EXT_PHY_CNTL_1_REG);
789         /* Set MAC i/f bits Reg23.12:11 */
790         reg_val = bitfield_replace(reg_val, MAC_IF_SELECTION_POS,
791                                    MAC_IF_SELECTION_WIDTH, mac_if);
792         /* Update Reg23.12:11 */
793         phy_write(phydev, MDIO_DEVAD_NONE,
794                   MSCC_PHY_EXT_PHY_CNTL_1_REG, reg_val);
795         /* Setup ExtPg_2 Register Access */
796         phy_write(phydev, MDIO_DEVAD_NONE,
797                   MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXT2);
798         /* Read Reg20E2 */
799         reg_val = phy_read(phydev, MDIO_DEVAD_NONE,
800                            MSCC_PHY_RGMII_CNTL_REG);
801         reg_val = bitfield_replace(reg_val, RX_CLK_OUT_POS,
802                                    RX_CLK_OUT_WIDTH, rx_clk_out);
803         /* Update Reg20E2.11 */
804         phy_write(phydev, MDIO_DEVAD_NONE,
805                   MSCC_PHY_RGMII_CNTL_REG, reg_val);
806         /* Before leaving - Change back to Std Page Register Access */
807         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
808                   MSCC_PHY_PAGE_STD);
809
810         return 0;
811 }
812
813 static int vsc8531_config(struct phy_device *phydev)
814 {
815         int  retval = -EINVAL;
816         u16  reg_val;
817         u16  rmii_clk_out;
818         enum vsc_phy_rgmii_skew  rx_clk_skew = VSC_PHY_RGMII_DELAY_1700_PS;
819         enum vsc_phy_rgmii_skew  tx_clk_skew = VSC_PHY_RGMII_DELAY_800_PS;
820         enum vsc_phy_clk_slew    edge_rate = VSC_PHY_CLK_SLEW_RATE_4;
821
822         /* For VSC8530/31 and VSC8540/41 the init scripts are the same */
823         mscc_vsc8531_vsc8541_init_scripts(phydev);
824
825         /* For VSC8530/31 the only MAC modes are RMII/RGMII. */
826         switch (phydev->interface) {
827         case PHY_INTERFACE_MODE_RMII:
828         case PHY_INTERFACE_MODE_RGMII:
829                 retval = vsc8531_vsc8541_mac_config(phydev);
830                 if (retval != 0)
831                         return retval;
832
833                 retval = mscc_phy_soft_reset(phydev);
834                 if (retval != 0)
835                         return retval;
836                 break;
837         default:
838                 printf("PHY 8530/31 MAC i/f Config Error: mac i/f = 0x%x\n",
839                        phydev->interface);
840                 return -EINVAL;
841         }
842         /* Default RMII Clk Output to 0=OFF/1=ON  */
843         rmii_clk_out = 0;
844
845         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
846                   MSCC_PHY_PAGE_EXT2);
847         reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG);
848
849         /* Reg20E2 - Update RGMII RX_Clk Skews. */
850         reg_val = bitfield_replace(reg_val, RGMII_RX_CLK_DELAY_POS,
851                                    RGMII_RX_CLK_DELAY_WIDTH, rx_clk_skew);
852         /* Reg20E2 - Update RGMII TX_Clk Skews. */
853         reg_val = bitfield_replace(reg_val, RGMII_TX_CLK_DELAY_POS,
854                                    RGMII_TX_CLK_DELAY_WIDTH, tx_clk_skew);
855
856         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG, reg_val);
857
858         reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL);
859         /* Reg27E2 - Update Clk Slew Rate. */
860         reg_val = bitfield_replace(reg_val, EDGE_RATE_CNTL_POS,
861                                    EDGE_RATE_CNTL_WIDTH, edge_rate);
862         /* Reg27E2 - Update RMII Clk Out. */
863         reg_val = bitfield_replace(reg_val, RMII_CLK_OUT_ENABLE_POS,
864                                    RMII_CLK_OUT_ENABLE_WIDTH, rmii_clk_out);
865         /* Update Reg27E2 */
866         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL, reg_val);
867         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
868                   MSCC_PHY_PAGE_STD);
869
870         return genphy_config_aneg(phydev);
871 }
872
873 static int vsc8541_config(struct phy_device *phydev)
874 {
875         int  retval = -EINVAL;
876         u16  reg_val;
877         u16  rmii_clk_out;
878         enum vsc_phy_rgmii_skew  rx_clk_skew = VSC_PHY_RGMII_DELAY_1700_PS;
879         enum vsc_phy_rgmii_skew  tx_clk_skew = VSC_PHY_RGMII_DELAY_800_PS;
880         enum vsc_phy_clk_slew    edge_rate = VSC_PHY_CLK_SLEW_RATE_4;
881
882         /* For VSC8530/31 and VSC8540/41 the init scripts are the same */
883         mscc_vsc8531_vsc8541_init_scripts(phydev);
884
885         /* For VSC8540/41 the only MAC modes are (G)MII and RMII/RGMII. */
886         switch (phydev->interface) {
887         case PHY_INTERFACE_MODE_MII:
888         case PHY_INTERFACE_MODE_GMII:
889         case PHY_INTERFACE_MODE_RMII:
890         case PHY_INTERFACE_MODE_RGMII:
891                 retval = vsc8531_vsc8541_mac_config(phydev);
892                 if (retval != 0)
893                         return retval;
894
895                 retval = mscc_phy_soft_reset(phydev);
896                 if (retval != 0)
897                         return retval;
898                 break;
899         default:
900                 printf("PHY 8541 MAC i/f config Error: mac i/f = 0x%x\n",
901                        phydev->interface);
902                 return -EINVAL;
903         }
904         /* Default RMII Clk Output to 0=OFF/1=ON  */
905         rmii_clk_out = 0;
906
907         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
908                   MSCC_PHY_PAGE_EXT2);
909         reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG);
910         /* Reg20E2 - Update RGMII RX_Clk Skews. */
911         reg_val = bitfield_replace(reg_val, RGMII_RX_CLK_DELAY_POS,
912                                    RGMII_RX_CLK_DELAY_WIDTH, rx_clk_skew);
913         /* Reg20E2 - Update RGMII TX_Clk Skews. */
914         reg_val = bitfield_replace(reg_val, RGMII_TX_CLK_DELAY_POS,
915                                    RGMII_TX_CLK_DELAY_WIDTH, tx_clk_skew);
916         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG, reg_val);
917
918         reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL);
919         /* Reg27E2 - Update Clk Slew Rate. */
920         reg_val = bitfield_replace(reg_val, EDGE_RATE_CNTL_POS,
921                                    EDGE_RATE_CNTL_WIDTH, edge_rate);
922         /* Reg27E2 - Update RMII Clk Out. */
923         reg_val = bitfield_replace(reg_val, RMII_CLK_OUT_ENABLE_POS,
924                                    RMII_CLK_OUT_ENABLE_WIDTH, rmii_clk_out);
925         /* Update Reg27E2 */
926         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL, reg_val);
927         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
928                   MSCC_PHY_PAGE_STD);
929
930         return genphy_config_aneg(phydev);
931 }
932
933 static int vsc8584_config_init(struct phy_device *phydev)
934 {
935         struct vsc85xx_priv *priv = phydev->priv;
936         int ret;
937         u16 addr;
938         u16 reg_val;
939         u16 val;
940
941         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
942                   MSCC_PHY_PAGE_EXT1);
943         addr = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_4);
944         addr >>= PHY_CNTL_4_ADDR_POS;
945
946         ret = priv->config_pre(phydev);
947         if (ret)
948                 return ret;
949
950         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
951                   MSCC_PHY_PAGE_GPIO);
952
953         if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
954                 val = MAC_CFG_QSGMII;
955         else
956                 val = MAC_CFG_SGMII;
957
958         reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_MAC_CFG_FASTLINK);
959         reg_val &= ~MAC_CFG_MASK;
960         reg_val |= val;
961         ret = phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_MAC_CFG_FASTLINK,
962                         reg_val);
963         if (ret)
964                 return ret;
965
966         reg_val = PROC_CMD_MCB_ACCESS_MAC_CONF | PROC_CMD_RST_CONF_PORT |
967                 PROC_CMD_READ_MOD_WRITE_PORT;
968         if (phydev->interface == PHY_INTERFACE_MODE_QSGMII)
969                 reg_val |= PROC_CMD_QSGMII_MAC;
970         else
971                 reg_val |= PROC_CMD_SGMII_MAC;
972
973         ret = vsc8584_cmd(phydev->bus, phydev->addr, reg_val);
974         if (ret)
975                 return ret;
976
977         mdelay(10);
978
979         /* Disable SerDes for 100Base-FX */
980         ret = vsc8584_cmd(phydev->bus, phydev->addr, PROC_CMD_FIBER_MEDIA_CONF |
981                           PROC_CMD_FIBER_PORT(addr) | PROC_CMD_FIBER_DISABLE |
982                           PROC_CMD_READ_MOD_WRITE_PORT |
983                           PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_100BASE_FX);
984         if (ret)
985                 return ret;
986
987         /* Disable SerDes for 1000Base-X */
988         ret = vsc8584_cmd(phydev->bus, phydev->addr, PROC_CMD_FIBER_MEDIA_CONF |
989                           PROC_CMD_FIBER_PORT(addr) | PROC_CMD_FIBER_DISABLE |
990                           PROC_CMD_READ_MOD_WRITE_PORT |
991                           PROC_CMD_RST_CONF_PORT | PROC_CMD_FIBER_1000BASE_X);
992         if (ret)
993                 return ret;
994
995         phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
996                   MSCC_PHY_PAGE_STD);
997         reg_val = phy_read(phydev, MDIO_DEVAD_NONE,
998                            MSCC_PHY_EXT_PHY_CNTL_1_REG);
999         reg_val &= ~(MEDIA_OP_MODE_MASK | VSC8584_MAC_IF_SELECTION_MASK);
1000         reg_val |= MEDIA_OP_MODE_COPPER |
1001                 (VSC8584_MAC_IF_SELECTION_SGMII <<
1002                  VSC8584_MAC_IF_SELECTION_POS);
1003         ret = phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_1_REG,
1004                         reg_val);
1005
1006         ret = mscc_phy_soft_reset(phydev);
1007         if (ret != 0)
1008                 return ret;
1009
1010         return genphy_config(phydev);
1011 }
1012
1013 static struct vsc85xx_priv vsc8584_priv = {
1014         .config_pre = vsc8584_config_pre_init,
1015 };
1016
1017 static int vsc8584_config(struct phy_device *phydev)
1018 {
1019         phydev->priv = &vsc8584_priv;
1020
1021         return vsc8584_config_init(phydev);
1022 }
1023
1024 static struct phy_driver VSC8530_driver = {
1025         .name = "Microsemi VSC8530",
1026         .uid = PHY_ID_VSC8530,
1027         .mask = 0x000ffff0,
1028         .features = PHY_BASIC_FEATURES,
1029         .config = &vsc8531_config,
1030         .startup = &mscc_startup,
1031         .shutdown = &genphy_shutdown,
1032 };
1033
1034 static struct phy_driver VSC8531_driver = {
1035         .name = "Microsemi VSC8531",
1036         .uid = PHY_ID_VSC8531,
1037         .mask = 0x000ffff0,
1038         .features = PHY_GBIT_FEATURES,
1039         .config = &vsc8531_config,
1040         .startup = &mscc_startup,
1041         .shutdown = &genphy_shutdown,
1042 };
1043
1044 static struct phy_driver VSC8540_driver = {
1045         .name = "Microsemi VSC8540",
1046         .uid = PHY_ID_VSC8540,
1047         .mask = 0x000ffff0,
1048         .features = PHY_BASIC_FEATURES,
1049         .config = &vsc8541_config,
1050         .startup = &mscc_startup,
1051         .shutdown = &genphy_shutdown,
1052 };
1053
1054 static struct phy_driver VSC8541_driver = {
1055         .name = "Microsemi VSC8541",
1056         .uid = PHY_ID_VSC8541,
1057         .mask = 0x000ffff0,
1058         .features = PHY_GBIT_FEATURES,
1059         .config = &vsc8541_config,
1060         .startup = &mscc_startup,
1061         .shutdown = &genphy_shutdown,
1062 };
1063
1064 static struct phy_driver VSC8584_driver = {
1065         .name = "Microsemi VSC8584",
1066         .uid = PHY_ID_VSC8584,
1067         .mask = 0x000ffff0,
1068         .features = PHY_GBIT_FEATURES,
1069         .config = &vsc8584_config,
1070         .startup = &mscc_startup,
1071         .shutdown = &genphy_shutdown,
1072 };
1073
1074 int phy_mscc_init(void)
1075 {
1076         phy_register(&VSC8530_driver);
1077         phy_register(&VSC8531_driver);
1078         phy_register(&VSC8540_driver);
1079         phy_register(&VSC8541_driver);
1080         phy_register(&VSC8584_driver);
1081
1082         return 0;
1083 }