Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: phy: mscc: consolidate a common RGMII delay implementation

It looks like the VSC8584 PHY driver is rolling its own RGMII delay
configuration code, despite the fact that the logic is mostly the same.

In fact only the register layout and position for the RGMII controls has
changed. So we need to adapt and parameterize the PHY-dependent bit
fields when calling the new generic function.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Antoine Tenart <antoine.tenart@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Vladimir Oltean and committed by
David S. Miller
2283a02b 148aa2a8

+48 -56
+8 -18
drivers/net/phy/mscc/mscc.h
··· 161 161 /* Extended Page 2 Registers */ 162 162 #define MSCC_PHY_CU_PMD_TX_CNTL 16 163 163 164 - #define MSCC_PHY_RGMII_SETTINGS 18 165 - #define RGMII_SKEW_RX_POS 1 166 - #define RGMII_SKEW_TX_POS 4 164 + /* RGMII setting controls at address 18E2, for VSC8572 and similar */ 165 + #define VSC8572_RGMII_CNTL 18 166 + #define VSC8572_RGMII_RX_DELAY_MASK 0x000E 167 + #define VSC8572_RGMII_TX_DELAY_MASK 0x0070 167 168 168 - /* RGMII skew values, in ns */ 169 - #define VSC8584_RGMII_SKEW_0_2 0 170 - #define VSC8584_RGMII_SKEW_0_8 1 171 - #define VSC8584_RGMII_SKEW_1_1 2 172 - #define VSC8584_RGMII_SKEW_1_7 3 173 - #define VSC8584_RGMII_SKEW_2_0 4 174 - #define VSC8584_RGMII_SKEW_2_3 5 175 - #define VSC8584_RGMII_SKEW_2_6 6 176 - #define VSC8584_RGMII_SKEW_3_4 7 177 - 178 - #define MSCC_PHY_RGMII_CNTL 20 179 - #define RGMII_RX_CLK_DELAY_MASK 0x0070 180 - #define RGMII_RX_CLK_DELAY_POS 4 181 - #define RGMII_TX_CLK_DELAY_MASK 0x0007 182 - #define RGMII_TX_CLK_DELAY_POS 0 169 + /* RGMII controls at address 20E2, for VSC8502 and similar */ 170 + #define VSC8502_RGMII_CNTL 20 171 + #define VSC8502_RGMII_RX_DELAY_MASK 0x0070 172 + #define VSC8502_RGMII_TX_DELAY_MASK 0x0007 183 173 184 174 #define MSCC_PHY_WOL_LOWER_MAC_ADDR 21 185 175 #define MSCC_PHY_WOL_MID_MAC_ADDR 22
+40 -38
drivers/net/phy/mscc/mscc_main.c
··· 520 520 return rc; 521 521 } 522 522 523 - static int vsc85xx_default_config(struct phy_device *phydev) 523 + /* Set the RGMII RX and TX clock skews individually, according to the PHY 524 + * interface type, to: 525 + * * 0.2 ns (their default, and lowest, hardware value) if delays should 526 + * not be enabled 527 + * * 2.0 ns (which causes the data to be sampled at exactly half way between 528 + * clock transitions at 1000 Mbps) if delays should be enabled 529 + */ 530 + static int vsc85xx_rgmii_set_skews(struct phy_device *phydev, u32 rgmii_cntl, 531 + u16 rgmii_rx_delay_mask, 532 + u16 rgmii_tx_delay_mask) 524 533 { 534 + u16 rgmii_rx_delay_pos = ffs(rgmii_rx_delay_mask) - 1; 535 + u16 rgmii_tx_delay_pos = ffs(rgmii_tx_delay_mask) - 1; 525 536 u16 reg_val = 0; 526 537 int rc; 527 - 528 - phydev->mdix_ctrl = ETH_TP_MDI_AUTO; 529 - 530 - if (!phy_interface_mode_is_rgmii(phydev->interface)) 531 - return 0; 532 538 533 539 mutex_lock(&phydev->lock); 534 540 535 541 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID || 536 542 phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) 537 - reg_val |= RGMII_CLK_DELAY_2_0_NS << RGMII_RX_CLK_DELAY_POS; 543 + reg_val |= RGMII_CLK_DELAY_2_0_NS << rgmii_rx_delay_pos; 538 544 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID || 539 545 phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) 540 - reg_val |= RGMII_CLK_DELAY_2_0_NS << RGMII_TX_CLK_DELAY_POS; 546 + reg_val |= RGMII_CLK_DELAY_2_0_NS << rgmii_tx_delay_pos; 541 547 542 548 rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2, 543 - MSCC_PHY_RGMII_CNTL, 544 - RGMII_RX_CLK_DELAY_MASK | RGMII_TX_CLK_DELAY_MASK, 549 + rgmii_cntl, 550 + rgmii_rx_delay_mask | rgmii_tx_delay_mask, 545 551 reg_val); 546 552 547 553 mutex_unlock(&phydev->lock); 548 554 549 555 return rc; 556 + } 557 + 558 + static int vsc85xx_default_config(struct phy_device *phydev) 559 + { 560 + int rc; 561 + 562 + phydev->mdix_ctrl = ETH_TP_MDI_AUTO; 563 + 564 + if (phy_interface_mode_is_rgmii(phydev->interface)) { 565 + rc = vsc85xx_rgmii_set_skews(phydev, VSC8502_RGMII_CNTL, 566 + VSC8502_RGMII_RX_DELAY_MASK, 567 + VSC8502_RGMII_TX_DELAY_MASK); 568 + if (rc) 569 + return rc; 570 + } 571 + 572 + return 0; 550 573 } 551 574 552 575 static int vsc85xx_get_tunable(struct phy_device *phydev, ··· 1324 1301 return false; 1325 1302 } 1326 1303 1327 - static void vsc8584_rgmii_set_skews(struct phy_device *phydev) 1328 - { 1329 - u32 skew_rx, skew_tx; 1330 - 1331 - /* We first set the Rx and Tx skews to their default value in h/w 1332 - * (0.2 ns). 1333 - */ 1334 - skew_rx = VSC8584_RGMII_SKEW_0_2; 1335 - skew_tx = VSC8584_RGMII_SKEW_0_2; 1336 - 1337 - /* We then set the skews based on the interface mode. */ 1338 - if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || 1339 - phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) 1340 - skew_rx = VSC8584_RGMII_SKEW_2_0; 1341 - if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || 1342 - phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) 1343 - skew_tx = VSC8584_RGMII_SKEW_2_0; 1344 - 1345 - /* Finally we apply the skews configuration. */ 1346 - phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2, 1347 - MSCC_PHY_RGMII_SETTINGS, 1348 - (0x7 << RGMII_SKEW_RX_POS) | (0x7 << RGMII_SKEW_TX_POS), 1349 - (skew_rx << RGMII_SKEW_RX_POS) | 1350 - (skew_tx << RGMII_SKEW_TX_POS)); 1351 - } 1352 - 1353 1304 static int vsc8584_config_init(struct phy_device *phydev) 1354 1305 { 1355 1306 struct vsc8531_private *vsc8531 = phydev->priv; ··· 1458 1461 if (ret) 1459 1462 return ret; 1460 1463 1461 - if (phy_interface_is_rgmii(phydev)) 1462 - vsc8584_rgmii_set_skews(phydev); 1464 + if (phy_interface_is_rgmii(phydev)) { 1465 + ret = vsc85xx_rgmii_set_skews(phydev, VSC8572_RGMII_CNTL, 1466 + VSC8572_RGMII_RX_DELAY_MASK, 1467 + VSC8572_RGMII_TX_DELAY_MASK); 1468 + if (ret) 1469 + return ret; 1470 + } 1463 1471 1464 1472 ret = genphy_soft_reset(phydev); 1465 1473 if (ret)