xref: /linux/drivers/net/dsa/mv88e6xxx/serdes.h (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
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 
30926eae60SHolger Brunck #define MV88E6352_SERDES_SPEC_CTRL2	0x1a
31926eae60SHolger Brunck #define MV88E6352_SERDES_OUT_AMP_MASK		0x0007
326d91782fSAndrew Lunn 
33d3cf7d8fSMarek Behún #define MV88E6341_PORT5_LANE		0x15
345bafeb6eSMarek Behún 
356335e9f2SAndrew Lunn #define MV88E6390_PORT9_LANE0		0x09
366335e9f2SAndrew Lunn #define MV88E6390_PORT9_LANE1		0x12
376335e9f2SAndrew Lunn #define MV88E6390_PORT9_LANE2		0x13
386335e9f2SAndrew Lunn #define MV88E6390_PORT9_LANE3		0x14
396335e9f2SAndrew Lunn #define MV88E6390_PORT10_LANE0		0x0a
406335e9f2SAndrew Lunn #define MV88E6390_PORT10_LANE1		0x15
416335e9f2SAndrew Lunn #define MV88E6390_PORT10_LANE2		0x16
426335e9f2SAndrew Lunn #define MV88E6390_PORT10_LANE3		0x17
436335e9f2SAndrew Lunn 
446335e9f2SAndrew Lunn /* 10GBASE-R and 10GBASE-X4/X2 */
45bf604bc9SRussell King #define MV88E6390_10G_CTRL1		(0x1000 + MDIO_CTRL1)
467019bba4SRussell King #define MV88E6390_10G_STAT1		(0x1000 + MDIO_STAT1)
47de776d0dSPavana Sharma #define MV88E6393X_10G_INT_ENABLE	0x9000
48de776d0dSPavana Sharma #define MV88E6393X_10G_INT_LINK_CHANGE	BIT(2)
49de776d0dSPavana Sharma #define MV88E6393X_10G_INT_STATUS	0x9001
506335e9f2SAndrew Lunn 
516335e9f2SAndrew Lunn /* 1000BASE-X and SGMII */
524c8b7350SRussell King #define MV88E6390_SGMII_BMCR		(0x2000 + MII_BMCR)
537e0e6243SRussell King #define MV88E6390_SGMII_BMSR		(0x2000 + MII_BMSR)
54a5a6858bSRussell King #define MV88E6390_SGMII_ADVERTISE	(0x2000 + MII_ADVERTISE)
55a5a6858bSRussell King #define MV88E6390_SGMII_LPA		(0x2000 + MII_LPA)
56efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_ENABLE	0xa001
57efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_SPEED_CHANGE	BIT(14)
58efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_DUPLEX_CHANGE	BIT(13)
59efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_PAGE_RX		BIT(12)
60efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_AN_COMPLETE		BIT(11)
61efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_LINK_DOWN		BIT(10)
62efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_LINK_UP		BIT(9)
63efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_SYMBOL_ERROR	BIT(8)
64efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_FALSE_CARRIER	BIT(7)
65efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_STATUS	0xa002
6672d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS	0xa003
6772d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPEED_MASK	GENMASK(15, 14)
6872d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPEED_1000	0x8000
6972d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPEED_100	0x4000
7072d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPEED_10	0x0000
7172d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL	BIT(13)
7272d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID BIT(11)
7372d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_LINK		BIT(10)
74a5a6858bSRussell King #define MV88E6390_SGMII_PHY_STATUS_TX_PAUSE	BIT(3)
75a5a6858bSRussell King #define MV88E6390_SGMII_PHY_STATUS_RX_PAUSE	BIT(2)
766335e9f2SAndrew Lunn 
770df95287SNikita Yushchenko /* Packet generator pad packet checker */
780df95287SNikita Yushchenko #define MV88E6390_PG_CONTROL		0xf010
790df95287SNikita Yushchenko #define MV88E6390_PG_CONTROL_ENABLE_PC		BIT(0)
800df95287SNikita Yushchenko 
81de776d0dSPavana Sharma #define MV88E6393X_PORT0_LANE			0x00
82de776d0dSPavana Sharma #define MV88E6393X_PORT9_LANE			0x09
83de776d0dSPavana Sharma #define MV88E6393X_PORT10_LANE			0x0a
84de776d0dSPavana Sharma 
85de776d0dSPavana Sharma /* Port Operational Configuration */
86de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC			0xf002
87de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_1000BASEX	0x0000
88de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_2500BASEX	0x0001
89de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_SGMII_PHY	0x0002
90de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_SGMII_MAC	0x0003
91de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_5GBASER	0x0004
92de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_10GBASER	0x0005
93de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_USXGMII_PHY	0x0006
94de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_USXGMII_MAC	0x0007
95de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PCS_MASK		0x0007
96de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_RESET		BIT(15)
97de776d0dSPavana Sharma #define MV88E6393X_SERDES_POC_PDOWN		BIT(5)
98163000dbSMarek Behún #define MV88E6393X_SERDES_POC_AN		BIT(3)
997527d662SMarek Behún #define MV88E6393X_SERDES_CTRL1			0xf003
1007527d662SMarek Behún #define MV88E6393X_SERDES_CTRL1_TX_PDOWN	BIT(9)
1017527d662SMarek Behún #define MV88E6393X_SERDES_CTRL1_RX_PDOWN	BIT(8)
102de776d0dSPavana Sharma 
103de776d0dSPavana Sharma #define MV88E6393X_ERRATA_4_8_REG		0xF074
104de776d0dSPavana Sharma #define MV88E6393X_ERRATA_4_8_BIT		BIT(14)
105de776d0dSPavana Sharma 
106193c5b26SPavana Sharma int mv88e6185_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
107193c5b26SPavana Sharma int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
108193c5b26SPavana Sharma int mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
109193c5b26SPavana Sharma int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
110193c5b26SPavana Sharma int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
111de776d0dSPavana Sharma int mv88e6393x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
112a5a6858bSRussell King int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
113193c5b26SPavana Sharma 				int lane, unsigned int mode,
114a5a6858bSRussell King 				phy_interface_t interface,
115a5a6858bSRussell King 				const unsigned long *advertise);
116a5a6858bSRussell King int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
117193c5b26SPavana Sharma 				int lane, unsigned int mode,
118a5a6858bSRussell King 				phy_interface_t interface,
119a5a6858bSRussell King 				const unsigned long *advertise);
120f5be107cSChris Packham int mv88e6185_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
121193c5b26SPavana Sharma 				   int lane, struct phylink_link_state *state);
122a5a6858bSRussell King int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
123193c5b26SPavana Sharma 				   int lane, struct phylink_link_state *state);
124a5a6858bSRussell King int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
125193c5b26SPavana Sharma 				   int lane, struct phylink_link_state *state);
126de776d0dSPavana Sharma int mv88e6393x_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
127de776d0dSPavana Sharma 				    int lane, struct phylink_link_state *state);
128a5a6858bSRussell King int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
129193c5b26SPavana Sharma 				    int lane);
130a5a6858bSRussell King int mv88e6390_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
131193c5b26SPavana Sharma 				    int lane);
132a5a6858bSRussell King int mv88e6352_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
133193c5b26SPavana Sharma 				 int lane, int speed, int duplex);
134a5a6858bSRussell King int mv88e6390_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
135193c5b26SPavana Sharma 				 int lane, int speed, int duplex);
1364241ef52SVivien Didelot unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip,
1374241ef52SVivien Didelot 					  int port);
1384241ef52SVivien Didelot unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip,
1394241ef52SVivien Didelot 					  int port);
140193c5b26SPavana Sharma int mv88e6185_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
141f5be107cSChris Packham 			   bool up);
142193c5b26SPavana Sharma int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
143dc272f60SVivien Didelot 			   bool on);
144193c5b26SPavana Sharma int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
145dc272f60SVivien Didelot 			   bool on);
146de776d0dSPavana Sharma int mv88e6393x_serdes_power(struct mv88e6xxx_chip *chip, int port, int lane,
147de776d0dSPavana Sharma 			    bool on);
148de776d0dSPavana Sharma int mv88e6393x_serdes_setup_errata(struct mv88e6xxx_chip *chip);
149193c5b26SPavana Sharma int mv88e6097_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane,
1505c19bc8bSChris Packham 				bool enable);
151193c5b26SPavana Sharma int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane,
15261a46b41SVivien Didelot 				bool enable);
153193c5b26SPavana Sharma int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, int lane,
15461a46b41SVivien Didelot 				bool enable);
155de776d0dSPavana Sharma int mv88e6393x_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port,
156de776d0dSPavana Sharma 				 int lane, bool enable);
1575c19bc8bSChris Packham irqreturn_t mv88e6097_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
158193c5b26SPavana Sharma 					int lane);
159907b9b9fSVivien Didelot irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
160193c5b26SPavana Sharma 					int lane);
161907b9b9fSVivien Didelot irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
162193c5b26SPavana Sharma 					int lane);
163de776d0dSPavana Sharma irqreturn_t mv88e6393x_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
164de776d0dSPavana Sharma 					 int lane);
165cda9f4aaSAndrew Lunn int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port);
16665f60e45SAndrew Lunn int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
167cda9f4aaSAndrew Lunn 				 int port, uint8_t *data);
16865f60e45SAndrew Lunn int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
169cda9f4aaSAndrew Lunn 			       uint64_t *data);
1700df95287SNikita Yushchenko int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port);
1710df95287SNikita Yushchenko int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip,
1720df95287SNikita Yushchenko 				 int port, uint8_t *data);
1730df95287SNikita Yushchenko int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
1740df95287SNikita Yushchenko 			       uint64_t *data);
1754382172fSAndrew Lunn 
176d3f88a24SAndrew Lunn int mv88e6352_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port);
177d3f88a24SAndrew Lunn void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p);
178bf3504ceSAndrew Lunn int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port);
179bf3504ceSAndrew Lunn void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p);
180d3f88a24SAndrew Lunn 
181926eae60SHolger Brunck int mv88e6352_serdes_set_tx_amplitude(struct mv88e6xxx_chip *chip, int port,
182926eae60SHolger Brunck 				      int val);
183926eae60SHolger Brunck 
184193c5b26SPavana Sharma /* Return the (first) SERDES lane address a port is using, -errno otherwise. */
185193c5b26SPavana Sharma static inline int mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip,
1865122d4ecSVivien Didelot 					    int port)
1875122d4ecSVivien Didelot {
1885122d4ecSVivien Didelot 	if (!chip->info->ops->serdes_get_lane)
189193c5b26SPavana Sharma 		return -EOPNOTSUPP;
1905122d4ecSVivien Didelot 
1915122d4ecSVivien Didelot 	return chip->info->ops->serdes_get_lane(chip, port);
1925122d4ecSVivien Didelot }
1935122d4ecSVivien Didelot 
194dc272f60SVivien Didelot static inline int mv88e6xxx_serdes_power_up(struct mv88e6xxx_chip *chip,
195193c5b26SPavana Sharma 					    int port, int lane)
196dc272f60SVivien Didelot {
197dc272f60SVivien Didelot 	if (!chip->info->ops->serdes_power)
198dc272f60SVivien Didelot 		return -EOPNOTSUPP;
199dc272f60SVivien Didelot 
200dc272f60SVivien Didelot 	return chip->info->ops->serdes_power(chip, port, lane, true);
201dc272f60SVivien Didelot }
202dc272f60SVivien Didelot 
203dc272f60SVivien Didelot static inline int mv88e6xxx_serdes_power_down(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, false);
210dc272f60SVivien Didelot }
211dc272f60SVivien Didelot 
2124241ef52SVivien Didelot static inline unsigned int
2134241ef52SVivien Didelot mv88e6xxx_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
2144241ef52SVivien Didelot {
2154241ef52SVivien Didelot 	if (!chip->info->ops->serdes_irq_mapping)
2164241ef52SVivien Didelot 		return 0;
2174241ef52SVivien Didelot 
2184241ef52SVivien Didelot 	return chip->info->ops->serdes_irq_mapping(chip, port);
2194241ef52SVivien Didelot }
220734447d4SAndrew Lunn 
22161a46b41SVivien Didelot static inline int mv88e6xxx_serdes_irq_enable(struct mv88e6xxx_chip *chip,
222193c5b26SPavana Sharma 					      int port, int lane)
22361a46b41SVivien Didelot {
22461a46b41SVivien Didelot 	if (!chip->info->ops->serdes_irq_enable)
22561a46b41SVivien Didelot 		return -EOPNOTSUPP;
22661a46b41SVivien Didelot 
22761a46b41SVivien Didelot 	return chip->info->ops->serdes_irq_enable(chip, port, lane, true);
22861a46b41SVivien Didelot }
22961a46b41SVivien Didelot 
23061a46b41SVivien Didelot static inline int mv88e6xxx_serdes_irq_disable(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, false);
23761a46b41SVivien Didelot }
23861a46b41SVivien Didelot 
239907b9b9fSVivien Didelot static inline irqreturn_t
240193c5b26SPavana Sharma mv88e6xxx_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, int lane)
241907b9b9fSVivien Didelot {
242907b9b9fSVivien Didelot 	if (!chip->info->ops->serdes_irq_status)
243907b9b9fSVivien Didelot 		return IRQ_NONE;
244907b9b9fSVivien Didelot 
245907b9b9fSVivien Didelot 	return chip->info->ops->serdes_irq_status(chip, port, lane);
246907b9b9fSVivien Didelot }
247907b9b9fSVivien Didelot 
2486d91782fSAndrew Lunn #endif
249