12874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 26d91782fSAndrew Lunn /* 36d91782fSAndrew Lunn * Marvell 88E6xxx SERDES manipulation, via SMI bus 46d91782fSAndrew Lunn * 56d91782fSAndrew Lunn * Copyright (c) 2008 Marvell Semiconductor 66d91782fSAndrew Lunn * 76d91782fSAndrew Lunn * Copyright (c) 2016 Andrew Lunn <andrew@lunn.ch> 86d91782fSAndrew Lunn */ 96d91782fSAndrew Lunn 106d91782fSAndrew Lunn #ifndef _MV88E6XXX_SERDES_H 116d91782fSAndrew Lunn #define _MV88E6XXX_SERDES_H 126d91782fSAndrew Lunn 134d5f2ba7SVivien Didelot #include "chip.h" 146d91782fSAndrew Lunn 15*05407b0eSRussell King (Oracle) struct phylink_link_state; 16*05407b0eSRussell King (Oracle) 176d91782fSAndrew Lunn #define MV88E6352_ADDR_SERDES 0x0f 186d91782fSAndrew Lunn #define MV88E6352_SERDES_PAGE_FIBER 0x01 194382172fSAndrew Lunn #define MV88E6352_SERDES_IRQ 0x0b 204382172fSAndrew Lunn #define MV88E6352_SERDES_INT_ENABLE 0x12 214382172fSAndrew Lunn #define MV88E6352_SERDES_INT_SPEED_CHANGE BIT(14) 224382172fSAndrew Lunn #define MV88E6352_SERDES_INT_DUPLEX_CHANGE BIT(13) 234382172fSAndrew Lunn #define MV88E6352_SERDES_INT_PAGE_RX BIT(12) 244382172fSAndrew Lunn #define MV88E6352_SERDES_INT_AN_COMPLETE BIT(11) 254382172fSAndrew Lunn #define MV88E6352_SERDES_INT_LINK_CHANGE BIT(10) 264382172fSAndrew Lunn #define MV88E6352_SERDES_INT_SYMBOL_ERROR BIT(9) 274382172fSAndrew Lunn #define MV88E6352_SERDES_INT_FALSE_CARRIER BIT(8) 284382172fSAndrew Lunn #define MV88E6352_SERDES_INT_FIFO_OVER_UNDER BIT(7) 294382172fSAndrew Lunn #define MV88E6352_SERDES_INT_FIBRE_ENERGY BIT(4) 304382172fSAndrew Lunn #define MV88E6352_SERDES_INT_STATUS 0x13 314382172fSAndrew Lunn 32926eae60SHolger Brunck #define MV88E6352_SERDES_SPEC_CTRL2 0x1a 33926eae60SHolger Brunck #define MV88E6352_SERDES_OUT_AMP_MASK 0x0007 346d91782fSAndrew Lunn 35d3cf7d8fSMarek Behún #define MV88E6341_PORT5_LANE 0x15 365bafeb6eSMarek Behún 376335e9f2SAndrew Lunn #define MV88E6390_PORT9_LANE0 0x09 386335e9f2SAndrew Lunn #define MV88E6390_PORT9_LANE1 0x12 396335e9f2SAndrew Lunn #define MV88E6390_PORT9_LANE2 0x13 406335e9f2SAndrew Lunn #define MV88E6390_PORT9_LANE3 0x14 416335e9f2SAndrew Lunn #define MV88E6390_PORT10_LANE0 0x0a 426335e9f2SAndrew Lunn #define MV88E6390_PORT10_LANE1 0x15 436335e9f2SAndrew Lunn #define MV88E6390_PORT10_LANE2 0x16 446335e9f2SAndrew Lunn #define MV88E6390_PORT10_LANE3 0x17 456335e9f2SAndrew Lunn 466335e9f2SAndrew Lunn /* 10GBASE-R and 10GBASE-X4/X2 */ 47bf604bc9SRussell King #define MV88E6390_10G_CTRL1 (0x1000 + MDIO_CTRL1) 487019bba4SRussell King #define MV88E6390_10G_STAT1 (0x1000 + MDIO_STAT1) 49de776d0dSPavana Sharma #define MV88E6393X_10G_INT_ENABLE 0x9000 50de776d0dSPavana Sharma #define MV88E6393X_10G_INT_LINK_CHANGE BIT(2) 51de776d0dSPavana Sharma #define MV88E6393X_10G_INT_STATUS 0x9001 526335e9f2SAndrew Lunn 534a562127SMichal Smulski /* USXGMII */ 544a562127SMichal Smulski #define MV88E6390_USXGMII_LP_STATUS 0xf0a2 554a562127SMichal Smulski #define MV88E6390_USXGMII_PHY_STATUS 0xf0a6 564a562127SMichal Smulski 576335e9f2SAndrew Lunn /* 1000BASE-X and SGMII */ 584c8b7350SRussell King #define MV88E6390_SGMII_BMCR (0x2000 + MII_BMCR) 597e0e6243SRussell King #define MV88E6390_SGMII_BMSR (0x2000 + MII_BMSR) 60a5a6858bSRussell King #define MV88E6390_SGMII_ADVERTISE (0x2000 + MII_ADVERTISE) 61a5a6858bSRussell King #define MV88E6390_SGMII_LPA (0x2000 + MII_LPA) 62efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_ENABLE 0xa001 63efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_SPEED_CHANGE BIT(14) 64efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_DUPLEX_CHANGE BIT(13) 65efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_PAGE_RX BIT(12) 66efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_AN_COMPLETE BIT(11) 67efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_LINK_DOWN BIT(10) 68efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_LINK_UP BIT(9) 69efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_SYMBOL_ERROR BIT(8) 70efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_FALSE_CARRIER BIT(7) 71efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_STATUS 0xa002 7272d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS 0xa003 7372d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPEED_MASK GENMASK(15, 14) 7472d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPEED_1000 0x8000 7572d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPEED_100 0x4000 7672d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPEED_10 0x0000 7772d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL BIT(13) 7872d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID BIT(11) 7972d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_LINK BIT(10) 80a5a6858bSRussell King #define MV88E6390_SGMII_PHY_STATUS_TX_PAUSE BIT(3) 81a5a6858bSRussell King #define MV88E6390_SGMII_PHY_STATUS_RX_PAUSE BIT(2) 826335e9f2SAndrew Lunn 830df95287SNikita Yushchenko /* Packet generator pad packet checker */ 840df95287SNikita Yushchenko #define MV88E6390_PG_CONTROL 0xf010 850df95287SNikita Yushchenko #define MV88E6390_PG_CONTROL_ENABLE_PC BIT(0) 860df95287SNikita Yushchenko 87de776d0dSPavana Sharma #define MV88E6393X_PORT0_LANE 0x00 88de776d0dSPavana Sharma #define MV88E6393X_PORT9_LANE 0x09 89de776d0dSPavana Sharma #define MV88E6393X_PORT10_LANE 0x0a 90de776d0dSPavana Sharma 91de776d0dSPavana Sharma /* Port Operational Configuration */ 92de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC 0xf002 93de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_1000BASEX 0x0000 94de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_2500BASEX 0x0001 95de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_SGMII_PHY 0x0002 96de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_SGMII_MAC 0x0003 97de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_5GBASER 0x0004 98de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_10GBASER 0x0005 99de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_USXGMII_PHY 0x0006 100de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_USXGMII_MAC 0x0007 101de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_MASK 0x0007 102de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_RESET BIT(15) 103de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PDOWN BIT(5) 104163000dbSMarek Behún #define MV88E6393X_SERDES_POC_AN BIT(3) 1057527d662SMarek Behún #define MV88E6393X_SERDES_CTRL1 0xf003 1067527d662SMarek Behún #define MV88E6393X_SERDES_CTRL1_TX_PDOWN BIT(9) 1077527d662SMarek Behún #define MV88E6393X_SERDES_CTRL1_RX_PDOWN BIT(8) 108de776d0dSPavana Sharma 109de776d0dSPavana Sharma #define MV88E6393X_ERRATA_4_8_REG 0xF074 110de776d0dSPavana Sharma #define MV88E6393X_ERRATA_4_8_BIT BIT(14) 111de776d0dSPavana Sharma 112*05407b0eSRussell King (Oracle) int mv88e6xxx_pcs_decode_state(struct device *dev, u16 bmsr, u16 lpa, 113*05407b0eSRussell King (Oracle) u16 status, struct phylink_link_state *state); 114*05407b0eSRussell King (Oracle) 115193c5b26SPavana Sharma int mv88e6185_serdes_get_lane(struct mv88e6xxx_chip *chip, int port); 116193c5b26SPavana Sharma int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port); 117193c5b26SPavana Sharma int mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port); 118193c5b26SPavana Sharma int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port); 119193c5b26SPavana Sharma int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port); 120de776d0dSPavana Sharma int mv88e6393x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port); 121a5a6858bSRussell King int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port, 122193c5b26SPavana Sharma int lane, unsigned int mode, 123a5a6858bSRussell King phy_interface_t interface, 124a5a6858bSRussell King const unsigned long *advertise); 125a5a6858bSRussell King int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port, 126193c5b26SPavana Sharma int lane, unsigned int mode, 127a5a6858bSRussell King phy_interface_t interface, 128a5a6858bSRussell King const unsigned long *advertise); 129f5be107cSChris Packham int mv88e6185_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, 130193c5b26SPavana Sharma int lane, struct phylink_link_state *state); 131a5a6858bSRussell King int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, 132193c5b26SPavana Sharma int lane, struct phylink_link_state *state); 133a5a6858bSRussell King int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, 134193c5b26SPavana Sharma int lane, struct phylink_link_state *state); 135de776d0dSPavana Sharma int mv88e6393x_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port, 136de776d0dSPavana Sharma int lane, struct phylink_link_state *state); 137a5a6858bSRussell King int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port, 138193c5b26SPavana Sharma int lane); 139a5a6858bSRussell King int mv88e6390_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port, 140193c5b26SPavana Sharma int lane); 141a5a6858bSRussell King int mv88e6352_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port, 142193c5b26SPavana Sharma int lane, int speed, int duplex); 143a5a6858bSRussell King int mv88e6390_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port, 144193c5b26SPavana Sharma int lane, int speed, int duplex); 1454241ef52SVivien Didelot unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, 1464241ef52SVivien Didelot int port); 1474241ef52SVivien Didelot unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, 1484241ef52SVivien Didelot int port); 149193c5b26SPavana Sharma int mv88e6185_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane, 150f5be107cSChris Packham bool up); 151193c5b26SPavana Sharma int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane, 152dc272f60SVivien Didelot bool on); 153193c5b26SPavana Sharma int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane, 154dc272f60SVivien Didelot bool on); 155de776d0dSPavana Sharma int mv88e6393x_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane, 156de776d0dSPavana Sharma bool on); 157de776d0dSPavana Sharma int mv88e6393x_serdes_setup_errata(struct mv88e6xxx_chip *chip); 158193c5b26SPavana Sharma int mv88e6097_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane, 1595c19bc8bSChris Packham bool enable); 160193c5b26SPavana Sharma int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane, 16161a46b41SVivien Didelot bool enable); 162193c5b26SPavana Sharma int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane, 16361a46b41SVivien Didelot bool enable); 164de776d0dSPavana Sharma int mv88e6393x_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, 165de776d0dSPavana Sharma int lane, bool enable); 1665c19bc8bSChris Packham irqreturn_t mv88e6097_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, 167193c5b26SPavana Sharma int lane); 168907b9b9fSVivien Didelot irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, 169193c5b26SPavana Sharma int lane); 170907b9b9fSVivien Didelot irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, 171193c5b26SPavana Sharma int lane); 172de776d0dSPavana Sharma irqreturn_t mv88e6393x_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, 173de776d0dSPavana Sharma int lane); 174cda9f4aaSAndrew Lunn int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port); 17565f60e45SAndrew Lunn int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip, 176cda9f4aaSAndrew Lunn int port, uint8_t *data); 17765f60e45SAndrew Lunn int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, 178cda9f4aaSAndrew Lunn uint64_t *data); 1790df95287SNikita Yushchenko int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port); 1800df95287SNikita Yushchenko int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip, 1810df95287SNikita Yushchenko int port, uint8_t *data); 1820df95287SNikita Yushchenko int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, 1830df95287SNikita Yushchenko uint64_t *data); 1844382172fSAndrew Lunn 185d3f88a24SAndrew Lunn int mv88e6352_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port); 186d3f88a24SAndrew Lunn void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p); 187bf3504ceSAndrew Lunn int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port); 188bf3504ceSAndrew Lunn void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p); 189d3f88a24SAndrew Lunn 190926eae60SHolger Brunck int mv88e6352_serdes_set_tx_amplitude(struct mv88e6xxx_chip *chip, int port, 191926eae60SHolger Brunck int val); 192926eae60SHolger Brunck 193193c5b26SPavana Sharma /* Return the (first) SERDES lane address a port is using, -errno otherwise. */ 194193c5b26SPavana Sharma static inline int mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip, 1955122d4ecSVivien Didelot int port) 1965122d4ecSVivien Didelot { 1975122d4ecSVivien Didelot if (!chip->info->ops->serdes_get_lane) 198193c5b26SPavana Sharma return -EOPNOTSUPP; 1995122d4ecSVivien Didelot 2005122d4ecSVivien Didelot return chip->info->ops->serdes_get_lane(chip, port); 2015122d4ecSVivien Didelot } 2025122d4ecSVivien Didelot 203dc272f60SVivien Didelot static inline int mv88e6xxx_serdes_power_up(struct mv88e6xxx_chip *chip, 204193c5b26SPavana Sharma int port, int lane) 205dc272f60SVivien Didelot { 206dc272f60SVivien Didelot if (!chip->info->ops->serdes_power) 207dc272f60SVivien Didelot return -EOPNOTSUPP; 208dc272f60SVivien Didelot 209dc272f60SVivien Didelot return chip->info->ops->serdes_power(chip, port, lane, true); 210dc272f60SVivien Didelot } 211dc272f60SVivien Didelot 212dc272f60SVivien Didelot static inline int mv88e6xxx_serdes_power_down(struct mv88e6xxx_chip *chip, 213193c5b26SPavana Sharma int port, int lane) 214dc272f60SVivien Didelot { 215dc272f60SVivien Didelot if (!chip->info->ops->serdes_power) 216dc272f60SVivien Didelot return -EOPNOTSUPP; 217dc272f60SVivien Didelot 218dc272f60SVivien Didelot return chip->info->ops->serdes_power(chip, port, lane, false); 219dc272f60SVivien Didelot } 220dc272f60SVivien Didelot 2214241ef52SVivien Didelot static inline unsigned int 2224241ef52SVivien Didelot mv88e6xxx_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port) 2234241ef52SVivien Didelot { 2244241ef52SVivien Didelot if (!chip->info->ops->serdes_irq_mapping) 2254241ef52SVivien Didelot return 0; 2264241ef52SVivien Didelot 2274241ef52SVivien Didelot return chip->info->ops->serdes_irq_mapping(chip, port); 2284241ef52SVivien Didelot } 229734447d4SAndrew Lunn 23061a46b41SVivien Didelot static inline int mv88e6xxx_serdes_irq_enable(struct mv88e6xxx_chip *chip, 231193c5b26SPavana Sharma int port, int lane) 23261a46b41SVivien Didelot { 23361a46b41SVivien Didelot if (!chip->info->ops->serdes_irq_enable) 23461a46b41SVivien Didelot return -EOPNOTSUPP; 23561a46b41SVivien Didelot 23661a46b41SVivien Didelot return chip->info->ops->serdes_irq_enable(chip, port, lane, true); 23761a46b41SVivien Didelot } 23861a46b41SVivien Didelot 23961a46b41SVivien Didelot static inline int mv88e6xxx_serdes_irq_disable(struct mv88e6xxx_chip *chip, 240193c5b26SPavana Sharma int port, int lane) 24161a46b41SVivien Didelot { 24261a46b41SVivien Didelot if (!chip->info->ops->serdes_irq_enable) 24361a46b41SVivien Didelot return -EOPNOTSUPP; 24461a46b41SVivien Didelot 24561a46b41SVivien Didelot return chip->info->ops->serdes_irq_enable(chip, port, lane, false); 24661a46b41SVivien Didelot } 24761a46b41SVivien Didelot 248907b9b9fSVivien Didelot static inline irqreturn_t 249193c5b26SPavana Sharma mv88e6xxx_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, int lane) 250907b9b9fSVivien Didelot { 251907b9b9fSVivien Didelot if (!chip->info->ops->serdes_irq_status) 252907b9b9fSVivien Didelot return IRQ_NONE; 253907b9b9fSVivien Didelot 254907b9b9fSVivien Didelot return chip->info->ops->serdes_irq_status(chip, port, lane); 255907b9b9fSVivien Didelot } 256907b9b9fSVivien Didelot 2576d91782fSAndrew Lunn #endif 258