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