xref: /openbmc/linux/drivers/net/dsa/mv88e6xxx/serdes.h (revision 163000db)
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 
156d91782fSAndrew Lunn #define MV88E6352_ADDR_SERDES		0x0f
166d91782fSAndrew Lunn #define MV88E6352_SERDES_PAGE_FIBER	0x01
174382172fSAndrew Lunn #define MV88E6352_SERDES_IRQ		0x0b
184382172fSAndrew Lunn #define MV88E6352_SERDES_INT_ENABLE	0x12
194382172fSAndrew Lunn #define MV88E6352_SERDES_INT_SPEED_CHANGE	BIT(14)
204382172fSAndrew Lunn #define MV88E6352_SERDES_INT_DUPLEX_CHANGE	BIT(13)
214382172fSAndrew Lunn #define MV88E6352_SERDES_INT_PAGE_RX		BIT(12)
224382172fSAndrew Lunn #define MV88E6352_SERDES_INT_AN_COMPLETE	BIT(11)
234382172fSAndrew Lunn #define MV88E6352_SERDES_INT_LINK_CHANGE	BIT(10)
244382172fSAndrew Lunn #define MV88E6352_SERDES_INT_SYMBOL_ERROR	BIT(9)
254382172fSAndrew Lunn #define MV88E6352_SERDES_INT_FALSE_CARRIER	BIT(8)
264382172fSAndrew Lunn #define MV88E6352_SERDES_INT_FIFO_OVER_UNDER	BIT(7)
274382172fSAndrew Lunn #define MV88E6352_SERDES_INT_FIBRE_ENERGY	BIT(4)
284382172fSAndrew Lunn #define MV88E6352_SERDES_INT_STATUS	0x13
294382172fSAndrew Lunn 
306d91782fSAndrew Lunn 
31d3cf7d8fSMarek Behún #define MV88E6341_PORT5_LANE		0x15
325bafeb6eSMarek Behún 
336335e9f2SAndrew Lunn #define MV88E6390_PORT9_LANE0		0x09
346335e9f2SAndrew Lunn #define MV88E6390_PORT9_LANE1		0x12
356335e9f2SAndrew Lunn #define MV88E6390_PORT9_LANE2		0x13
366335e9f2SAndrew Lunn #define MV88E6390_PORT9_LANE3		0x14
376335e9f2SAndrew Lunn #define MV88E6390_PORT10_LANE0		0x0a
386335e9f2SAndrew Lunn #define MV88E6390_PORT10_LANE1		0x15
396335e9f2SAndrew Lunn #define MV88E6390_PORT10_LANE2		0x16
406335e9f2SAndrew Lunn #define MV88E6390_PORT10_LANE3		0x17
416335e9f2SAndrew Lunn 
426335e9f2SAndrew Lunn /* 10GBASE-R and 10GBASE-X4/X2 */
43bf604bc9SRussell King #define MV88E6390_10G_CTRL1		(0x1000 + MDIO_CTRL1)
447019bba4SRussell King #define MV88E6390_10G_STAT1		(0x1000 + MDIO_STAT1)
45de776d0dSPavana Sharma #define MV88E6393X_10G_INT_ENABLE	0x9000
46de776d0dSPavana Sharma #define MV88E6393X_10G_INT_LINK_CHANGE	BIT(2)
47de776d0dSPavana Sharma #define MV88E6393X_10G_INT_STATUS	0x9001
486335e9f2SAndrew Lunn 
496335e9f2SAndrew Lunn /* 1000BASE-X and SGMII */
504c8b7350SRussell King #define MV88E6390_SGMII_BMCR		(0x2000 + MII_BMCR)
517e0e6243SRussell King #define MV88E6390_SGMII_BMSR		(0x2000 + MII_BMSR)
52a5a6858bSRussell King #define MV88E6390_SGMII_ADVERTISE	(0x2000 + MII_ADVERTISE)
53a5a6858bSRussell King #define MV88E6390_SGMII_LPA		(0x2000 + MII_LPA)
54efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_ENABLE	0xa001
55efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_SPEED_CHANGE	BIT(14)
56efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_DUPLEX_CHANGE	BIT(13)
57efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_PAGE_RX		BIT(12)
58efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_AN_COMPLETE		BIT(11)
59efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_LINK_DOWN		BIT(10)
60efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_LINK_UP		BIT(9)
61efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_SYMBOL_ERROR	BIT(8)
62efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_FALSE_CARRIER	BIT(7)
63efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_STATUS	0xa002
6472d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS	0xa003
6572d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPEED_MASK	GENMASK(15, 14)
6672d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPEED_1000	0x8000
6772d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPEED_100	0x4000
6872d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPEED_10	0x0000
6972d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL	BIT(13)
7072d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID BIT(11)
7172d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_LINK		BIT(10)
72a5a6858bSRussell King #define MV88E6390_SGMII_PHY_STATUS_TX_PAUSE	BIT(3)
73a5a6858bSRussell King #define MV88E6390_SGMII_PHY_STATUS_RX_PAUSE	BIT(2)
746335e9f2SAndrew Lunn 
750df95287SNikita Yushchenko /* Packet generator pad packet checker */
760df95287SNikita Yushchenko #define MV88E6390_PG_CONTROL		0xf010
770df95287SNikita Yushchenko #define MV88E6390_PG_CONTROL_ENABLE_PC		BIT(0)
780df95287SNikita Yushchenko 
79de776d0dSPavana Sharma #define MV88E6393X_PORT0_LANE			0x00
80de776d0dSPavana Sharma #define MV88E6393X_PORT9_LANE			0x09
81de776d0dSPavana Sharma #define MV88E6393X_PORT10_LANE			0x0a
82de776d0dSPavana Sharma 
83de776d0dSPavana Sharma /* Port Operational Configuration */
84de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC			0xf002
85de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_1000BASEX	0x0000
86de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_2500BASEX	0x0001
87de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_SGMII_PHY	0x0002
88de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_SGMII_MAC	0x0003
89de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_5GBASER	0x0004
90de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_10GBASER	0x0005
91de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_USXGMII_PHY	0x0006
92de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_USXGMII_MAC	0x0007
93de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_MASK		0x0007
94de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_RESET		BIT(15)
95de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PDOWN		BIT(5)
96*163000dbSMarek Behún #define MV88E6393X_SERDES_POC_AN		BIT(3)
977527d662SMarek Behún #define MV88E6393X_SERDES_CTRL1			0xf003
987527d662SMarek Behún #define MV88E6393X_SERDES_CTRL1_TX_PDOWN	BIT(9)
997527d662SMarek Behún #define MV88E6393X_SERDES_CTRL1_RX_PDOWN	BIT(8)
100de776d0dSPavana Sharma 
101de776d0dSPavana Sharma #define MV88E6393X_ERRATA_4_8_REG		0xF074
102de776d0dSPavana Sharma #define MV88E6393X_ERRATA_4_8_BIT		BIT(14)
103de776d0dSPavana Sharma 
104193c5b26SPavana Sharma int mv88e6185_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
105193c5b26SPavana Sharma int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
106193c5b26SPavana Sharma int mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
107193c5b26SPavana Sharma int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
108193c5b26SPavana Sharma int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
109de776d0dSPavana Sharma int mv88e6393x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
110a5a6858bSRussell King int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
111193c5b26SPavana Sharma 				int lane, unsigned int mode,
112a5a6858bSRussell King 				phy_interface_t interface,
113a5a6858bSRussell King 				const unsigned long *advertise);
114a5a6858bSRussell King int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
115193c5b26SPavana Sharma 				int lane, unsigned int mode,
116a5a6858bSRussell King 				phy_interface_t interface,
117a5a6858bSRussell King 				const unsigned long *advertise);
118f5be107cSChris Packham int mv88e6185_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
119193c5b26SPavana Sharma 				   int lane, struct phylink_link_state *state);
120a5a6858bSRussell King int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
121193c5b26SPavana Sharma 				   int lane, struct phylink_link_state *state);
122a5a6858bSRussell King int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
123193c5b26SPavana Sharma 				   int lane, struct phylink_link_state *state);
124de776d0dSPavana Sharma int mv88e6393x_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
125de776d0dSPavana Sharma 				    int lane, struct phylink_link_state *state);
126a5a6858bSRussell King int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
127193c5b26SPavana Sharma 				    int lane);
128a5a6858bSRussell King int mv88e6390_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
129193c5b26SPavana Sharma 				    int lane);
130a5a6858bSRussell King int mv88e6352_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
131193c5b26SPavana Sharma 				 int lane, int speed, int duplex);
132a5a6858bSRussell King int mv88e6390_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
133193c5b26SPavana Sharma 				 int lane, int speed, int duplex);
1344241ef52SVivien Didelot unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip,
1354241ef52SVivien Didelot 					  int port);
1364241ef52SVivien Didelot unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip,
1374241ef52SVivien Didelot 					  int port);
138193c5b26SPavana Sharma int mv88e6185_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
139f5be107cSChris Packham 			   bool up);
140193c5b26SPavana Sharma int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
141dc272f60SVivien Didelot 			   bool on);
142193c5b26SPavana Sharma int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
143dc272f60SVivien Didelot 			   bool on);
144de776d0dSPavana Sharma int mv88e6393x_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
145de776d0dSPavana Sharma 			    bool on);
146de776d0dSPavana Sharma int mv88e6393x_serdes_setup_errata(struct mv88e6xxx_chip *chip);
147193c5b26SPavana Sharma int mv88e6097_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane,
1485c19bc8bSChris Packham 				bool enable);
149193c5b26SPavana Sharma int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane,
15061a46b41SVivien Didelot 				bool enable);
151193c5b26SPavana Sharma int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane,
15261a46b41SVivien Didelot 				bool enable);
153de776d0dSPavana Sharma int mv88e6393x_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port,
154de776d0dSPavana Sharma 				 int lane, bool enable);
1555c19bc8bSChris Packham irqreturn_t mv88e6097_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
156193c5b26SPavana Sharma 					int lane);
157907b9b9fSVivien Didelot irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
158193c5b26SPavana Sharma 					int lane);
159907b9b9fSVivien Didelot irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
160193c5b26SPavana Sharma 					int lane);
161de776d0dSPavana Sharma irqreturn_t mv88e6393x_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
162de776d0dSPavana Sharma 					 int lane);
163cda9f4aaSAndrew Lunn int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port);
16465f60e45SAndrew Lunn int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
165cda9f4aaSAndrew Lunn 				 int port, uint8_t *data);
16665f60e45SAndrew Lunn int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
167cda9f4aaSAndrew Lunn 			       uint64_t *data);
1680df95287SNikita Yushchenko int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port);
1690df95287SNikita Yushchenko int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip,
1700df95287SNikita Yushchenko 				 int port, uint8_t *data);
1710df95287SNikita Yushchenko int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
1720df95287SNikita Yushchenko 			       uint64_t *data);
1734382172fSAndrew Lunn 
174d3f88a24SAndrew Lunn int mv88e6352_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port);
175d3f88a24SAndrew Lunn void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p);
176bf3504ceSAndrew Lunn int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port);
177bf3504ceSAndrew Lunn void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p);
178d3f88a24SAndrew Lunn 
179193c5b26SPavana Sharma /* Return the (first) SERDES lane address a port is using, -errno otherwise. */
180193c5b26SPavana Sharma static inline int mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip,
1815122d4ecSVivien Didelot 					    int port)
1825122d4ecSVivien Didelot {
1835122d4ecSVivien Didelot 	if (!chip->info->ops->serdes_get_lane)
184193c5b26SPavana Sharma 		return -EOPNOTSUPP;
1855122d4ecSVivien Didelot 
1865122d4ecSVivien Didelot 	return chip->info->ops->serdes_get_lane(chip, port);
1875122d4ecSVivien Didelot }
1885122d4ecSVivien Didelot 
189dc272f60SVivien Didelot static inline int mv88e6xxx_serdes_power_up(struct mv88e6xxx_chip *chip,
190193c5b26SPavana Sharma 					    int port, int lane)
191dc272f60SVivien Didelot {
192dc272f60SVivien Didelot 	if (!chip->info->ops->serdes_power)
193dc272f60SVivien Didelot 		return -EOPNOTSUPP;
194dc272f60SVivien Didelot 
195dc272f60SVivien Didelot 	return chip->info->ops->serdes_power(chip, port, lane, true);
196dc272f60SVivien Didelot }
197dc272f60SVivien Didelot 
198dc272f60SVivien Didelot static inline int mv88e6xxx_serdes_power_down(struct mv88e6xxx_chip *chip,
199193c5b26SPavana Sharma 					      int port, int lane)
200dc272f60SVivien Didelot {
201dc272f60SVivien Didelot 	if (!chip->info->ops->serdes_power)
202dc272f60SVivien Didelot 		return -EOPNOTSUPP;
203dc272f60SVivien Didelot 
204dc272f60SVivien Didelot 	return chip->info->ops->serdes_power(chip, port, lane, false);
205dc272f60SVivien Didelot }
206dc272f60SVivien Didelot 
2074241ef52SVivien Didelot static inline unsigned int
2084241ef52SVivien Didelot mv88e6xxx_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
2094241ef52SVivien Didelot {
2104241ef52SVivien Didelot 	if (!chip->info->ops->serdes_irq_mapping)
2114241ef52SVivien Didelot 		return 0;
2124241ef52SVivien Didelot 
2134241ef52SVivien Didelot 	return chip->info->ops->serdes_irq_mapping(chip, port);
2144241ef52SVivien Didelot }
215734447d4SAndrew Lunn 
21661a46b41SVivien Didelot static inline int mv88e6xxx_serdes_irq_enable(struct mv88e6xxx_chip *chip,
217193c5b26SPavana Sharma 					      int port, int lane)
21861a46b41SVivien Didelot {
21961a46b41SVivien Didelot 	if (!chip->info->ops->serdes_irq_enable)
22061a46b41SVivien Didelot 		return -EOPNOTSUPP;
22161a46b41SVivien Didelot 
22261a46b41SVivien Didelot 	return chip->info->ops->serdes_irq_enable(chip, port, lane, true);
22361a46b41SVivien Didelot }
22461a46b41SVivien Didelot 
22561a46b41SVivien Didelot static inline int mv88e6xxx_serdes_irq_disable(struct mv88e6xxx_chip *chip,
226193c5b26SPavana Sharma 					       int port, int lane)
22761a46b41SVivien Didelot {
22861a46b41SVivien Didelot 	if (!chip->info->ops->serdes_irq_enable)
22961a46b41SVivien Didelot 		return -EOPNOTSUPP;
23061a46b41SVivien Didelot 
23161a46b41SVivien Didelot 	return chip->info->ops->serdes_irq_enable(chip, port, lane, false);
23261a46b41SVivien Didelot }
23361a46b41SVivien Didelot 
234907b9b9fSVivien Didelot static inline irqreturn_t
235193c5b26SPavana Sharma mv88e6xxx_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, int lane)
236907b9b9fSVivien Didelot {
237907b9b9fSVivien Didelot 	if (!chip->info->ops->serdes_irq_status)
238907b9b9fSVivien Didelot 		return IRQ_NONE;
239907b9b9fSVivien Didelot 
240907b9b9fSVivien Didelot 	return chip->info->ops->serdes_irq_status(chip, port, lane);
241907b9b9fSVivien Didelot }
242907b9b9fSVivien Didelot 
2436d91782fSAndrew Lunn #endif
244