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

net: phy: broadcom: Add BCM54810 PHY entry

The BCM54810 PHY requires some semi-unique configuration, which results
in some additional configuration in addition to the standard config.
Also, some users of the BCM54810 require the PHY lanes to be swapped.
Since there is no way to detect this, add a device tree query to see if
it is applicable.

Inspired-by: Vikas Soni <vsoni@broadcom.com>
Signed-off-by: Jon Mason <jon.mason@broadcom.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jon Mason and committed by
David S. Miller
b14995ac 3b9feb60

+67 -2
+1 -1
drivers/net/phy/Kconfig
··· 217 217 select BCM_NET_PHYLIB 218 218 ---help--- 219 219 Currently supports the BCM5411, BCM5421, BCM5461, BCM54616S, BCM5464, 220 - BCM5481 and BCM5482 PHYs. 220 + BCM5481, BCM54810 and BCM5482 PHYs. 221 221 222 222 config CICADA_PHY 223 223 tristate "Cicada PHYs"
+57 -1
drivers/net/phy/broadcom.c
··· 18 18 #include <linux/module.h> 19 19 #include <linux/phy.h> 20 20 #include <linux/brcmphy.h> 21 - 21 + #include <linux/of.h> 22 22 23 23 #define BRCM_PHY_MODEL(phydev) \ 24 24 ((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask) ··· 43 43 static int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val) 44 44 { 45 45 return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val); 46 + } 47 + 48 + static int bcm54810_config(struct phy_device *phydev) 49 + { 50 + int rc, val; 51 + 52 + val = bcm_phy_read_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL); 53 + val &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN; 54 + rc = bcm_phy_write_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL, 55 + val); 56 + if (rc < 0) 57 + return rc; 58 + 59 + val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC); 60 + val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN; 61 + val |= MII_BCM54XX_AUXCTL_MISC_WREN; 62 + rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC, 63 + val); 64 + if (rc < 0) 65 + return rc; 66 + 67 + val = bcm_phy_read_shadow(phydev, BCM54810_SHD_CLK_CTL); 68 + val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN; 69 + rc = bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val); 70 + if (rc < 0) 71 + return rc; 72 + 73 + return 0; 46 74 } 47 75 48 76 /* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */ ··· 245 217 (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE)) 246 218 bcm54xx_adjust_rxrefclk(phydev); 247 219 220 + if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810) { 221 + err = bcm54810_config(phydev); 222 + if (err) 223 + return err; 224 + } 225 + 248 226 bcm54xx_phydsp_config(phydev); 249 227 250 228 return 0; ··· 348 314 349 315 static int bcm5481_config_aneg(struct phy_device *phydev) 350 316 { 317 + struct device_node *np = phydev->mdio.dev.of_node; 351 318 int ret; 352 319 353 320 /* Aneg firsly. */ ··· 377 342 /* Write bits 14:0. */ 378 343 reg |= (1 << 15); 379 344 phy_write(phydev, 0x18, reg); 345 + } 346 + 347 + if (of_property_read_bool(np, "enet-phy-lane-swap")) { 348 + /* Lane Swap - Undocumented register...magic! */ 349 + ret = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_SEL_ER + 0x9, 350 + 0x11B); 351 + if (ret < 0) 352 + return ret; 380 353 } 381 354 382 355 return ret; ··· 621 578 .ack_interrupt = bcm_phy_ack_intr, 622 579 .config_intr = bcm_phy_config_intr, 623 580 }, { 581 + .phy_id = PHY_ID_BCM54810, 582 + .phy_id_mask = 0xfffffff0, 583 + .name = "Broadcom BCM54810", 584 + .features = PHY_GBIT_FEATURES | 585 + SUPPORTED_Pause | SUPPORTED_Asym_Pause, 586 + .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, 587 + .config_init = bcm54xx_config_init, 588 + .config_aneg = bcm5481_config_aneg, 589 + .read_status = genphy_read_status, 590 + .ack_interrupt = bcm_phy_ack_intr, 591 + .config_intr = bcm_phy_config_intr, 592 + }, { 624 593 .phy_id = PHY_ID_BCM5482, 625 594 .phy_id_mask = 0xfffffff0, 626 595 .name = "Broadcom BCM5482", ··· 716 661 { PHY_ID_BCM54616S, 0xfffffff0 }, 717 662 { PHY_ID_BCM5464, 0xfffffff0 }, 718 663 { PHY_ID_BCM5481, 0xfffffff0 }, 664 + { PHY_ID_BCM54810, 0xfffffff0 }, 719 665 { PHY_ID_BCM5482, 0xfffffff0 }, 720 666 { PHY_ID_BCM50610, 0xfffffff0 }, 721 667 { PHY_ID_BCM50610M, 0xfffffff0 },
+9
include/linux/brcmphy.h
··· 13 13 #define PHY_ID_BCM5241 0x0143bc30 14 14 #define PHY_ID_BCMAC131 0x0143bc70 15 15 #define PHY_ID_BCM5481 0x0143bca0 16 + #define PHY_ID_BCM54810 0x03625d00 16 17 #define PHY_ID_BCM5482 0x0143bcb0 17 18 #define PHY_ID_BCM5411 0x00206070 18 19 #define PHY_ID_BCM5421 0x002060e0 ··· 57 56 #define PHY_BRCM_EXT_IBND_TX_ENABLE 0x00002000 58 57 #define PHY_BRCM_CLEAR_RGMII_MODE 0x00004000 59 58 #define PHY_BRCM_DIS_TXCRXC_NOENRGY 0x00008000 59 + 60 60 /* Broadcom BCM7xxx specific workarounds */ 61 61 #define PHY_BRCM_7XXX_REV(x) (((x) >> 8) & 0xff) 62 62 #define PHY_BRCM_7XXX_PATCH(x) ((x) & 0xff) ··· 113 111 #define MII_BCM54XX_AUXCTL_MISC_RDSEL_MISC 0x7000 114 112 #define MII_BCM54XX_AUXCTL_SHDWSEL_MISC 0x0007 115 113 #define MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT 12 114 + #define MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN (1 << 8) 116 115 117 116 #define MII_BCM54XX_AUXCTL_SHDWSEL_MASK 0x0007 118 117 ··· 194 191 #define BCM5482_SSD_SGMII_SLAVE 0x15 /* SGMII Slave Register */ 195 192 #define BCM5482_SSD_SGMII_SLAVE_EN 0x0002 /* Slave mode enable */ 196 193 #define BCM5482_SSD_SGMII_SLAVE_AD 0x0001 /* Slave auto-detection */ 194 + 195 + /* BCM54810 Registers */ 196 + #define BCM54810_EXP_BROADREACH_LRE_MISC_CTL (MII_BCM54XX_EXP_SEL_ER + 0x90) 197 + #define BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN (1 << 0) 198 + #define BCM54810_SHD_CLK_CTL 0x3 199 + #define BCM54810_SHD_CLK_CTL_GTXCLK_EN (1 << 9) 197 200 198 201 199 202 /*****************************************************************************/