xref: /openbmc/linux/drivers/net/dsa/mv88e6xxx/serdes.h (revision 4241ef52)
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 */
436335e9f2SAndrew Lunn #define MV88E6390_PCS_CONTROL_1		0x1000
446335e9f2SAndrew Lunn #define MV88E6390_PCS_CONTROL_1_RESET		BIT(15)
456335e9f2SAndrew Lunn #define MV88E6390_PCS_CONTROL_1_LOOPBACK	BIT(14)
466335e9f2SAndrew Lunn #define MV88E6390_PCS_CONTROL_1_SPEED		BIT(13)
476335e9f2SAndrew Lunn #define MV88E6390_PCS_CONTROL_1_PDOWN		BIT(11)
486335e9f2SAndrew Lunn 
496335e9f2SAndrew Lunn /* 1000BASE-X and SGMII */
506335e9f2SAndrew Lunn #define MV88E6390_SGMII_CONTROL		0x2000
516335e9f2SAndrew Lunn #define MV88E6390_SGMII_CONTROL_RESET		BIT(15)
526335e9f2SAndrew Lunn #define MV88E6390_SGMII_CONTROL_LOOPBACK	BIT(14)
536335e9f2SAndrew Lunn #define MV88E6390_SGMII_CONTROL_PDOWN		BIT(11)
54efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_STATUS		0x2001
55efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_STATUS_AN_DONE		BIT(5)
56efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_STATUS_REMOTE_FAULT	BIT(4)
57efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_STATUS_LINK		BIT(2)
58efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_ENABLE	0xa001
59efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_SPEED_CHANGE	BIT(14)
60efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_DUPLEX_CHANGE	BIT(13)
61efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_PAGE_RX		BIT(12)
62efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_AN_COMPLETE		BIT(11)
63efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_LINK_DOWN		BIT(10)
64efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_LINK_UP		BIT(9)
65efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_SYMBOL_ERROR	BIT(8)
66efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_FALSE_CARRIER	BIT(7)
67efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_STATUS	0xa002
6872d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS	0xa003
6972d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPEED_MASK	GENMASK(15, 14)
7072d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPEED_1000	0x8000
7172d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPEED_100	0x4000
7272d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPEED_10	0x0000
7372d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL	BIT(13)
7472d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID BIT(11)
7572d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_LINK		BIT(10)
766335e9f2SAndrew Lunn 
7717deaf5cSMarek Behún /* Put the SERDES lane address a port is using into *lane. If a port has
7817deaf5cSMarek Behún  * multiple lanes, should put the first lane the port is using. If a port does
7917deaf5cSMarek Behún  * not have a lane, return -ENODEV.
8017deaf5cSMarek Behún  */
8117deaf5cSMarek Behún static inline int mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip,
8217deaf5cSMarek Behún 					    int port, u8 *lane)
8317deaf5cSMarek Behún {
8417deaf5cSMarek Behún 	if (!chip->info->ops->serdes_get_lane)
8517deaf5cSMarek Behún 		return -EOPNOTSUPP;
8617deaf5cSMarek Behún 
8717deaf5cSMarek Behún 	return chip->info->ops->serdes_get_lane(chip, port, lane);
8817deaf5cSMarek Behún }
8917deaf5cSMarek Behún 
90d3cf7d8fSMarek Behún int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane);
9117deaf5cSMarek Behún int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane);
9217deaf5cSMarek Behún int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane);
934241ef52SVivien Didelot unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip,
944241ef52SVivien Didelot 					  int port);
954241ef52SVivien Didelot unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip,
964241ef52SVivien Didelot 					  int port);
976d91782fSAndrew Lunn int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on);
986335e9f2SAndrew Lunn int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on);
99efd1ba6aSAndrew Lunn int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port);
100efd1ba6aSAndrew Lunn void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port);
101cda9f4aaSAndrew Lunn int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port);
10265f60e45SAndrew Lunn int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
103cda9f4aaSAndrew Lunn 				 int port, uint8_t *data);
10465f60e45SAndrew Lunn int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
105cda9f4aaSAndrew Lunn 			       uint64_t *data);
106734447d4SAndrew Lunn int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port,
10717deaf5cSMarek Behún 				u8 lane);
108734447d4SAndrew Lunn int mv88e6390_serdes_irq_disable(struct mv88e6xxx_chip *chip, int port,
10917deaf5cSMarek Behún 				 u8 lane);
1104382172fSAndrew Lunn int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port);
1114382172fSAndrew Lunn void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port);
1124382172fSAndrew Lunn 
1134241ef52SVivien Didelot static inline unsigned int
1144241ef52SVivien Didelot mv88e6xxx_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
1154241ef52SVivien Didelot {
1164241ef52SVivien Didelot 	if (!chip->info->ops->serdes_irq_mapping)
1174241ef52SVivien Didelot 		return 0;
1184241ef52SVivien Didelot 
1194241ef52SVivien Didelot 	return chip->info->ops->serdes_irq_mapping(chip, port);
1204241ef52SVivien Didelot }
121734447d4SAndrew Lunn 
1226d91782fSAndrew Lunn #endif
123