xref: /linux/drivers/net/dsa/mv88e6xxx/port_hidden.c (revision 609070133aff1f2b533561758aa97c947fa534c8)
1*60907013SMarek Behún // SPDX-License-Identifier: GPL-2.0-or-later
2*60907013SMarek Behún /*
3*60907013SMarek Behún  * Marvell 88E6xxx Switch Hidden Registers support
4*60907013SMarek Behún  *
5*60907013SMarek Behún  * Copyright (c) 2008 Marvell Semiconductor
6*60907013SMarek Behún  *
7*60907013SMarek Behún  * Copyright (c) 2019 Andrew Lunn <andrew@lunn.ch>
8*60907013SMarek Behún  */
9*60907013SMarek Behún 
10*60907013SMarek Behún #include <linux/bitfield.h>
11*60907013SMarek Behún 
12*60907013SMarek Behún #include "chip.h"
13*60907013SMarek Behún #include "port.h"
14*60907013SMarek Behún 
15*60907013SMarek Behún /* The mv88e6390 and mv88e6341 have some hidden registers used for debug and
16*60907013SMarek Behún  * development. The errata also makes use of them.
17*60907013SMarek Behún  */
18*60907013SMarek Behún int mv88e6xxx_port_hidden_write(struct mv88e6xxx_chip *chip, int block,
19*60907013SMarek Behún 				int port, int reg, u16 val)
20*60907013SMarek Behún {
21*60907013SMarek Behún 	u16 ctrl;
22*60907013SMarek Behún 	int err;
23*60907013SMarek Behún 
24*60907013SMarek Behún 	err = mv88e6xxx_port_write(chip, MV88E6XXX_PORT_RESERVED_1A_DATA_PORT,
25*60907013SMarek Behún 				   MV88E6XXX_PORT_RESERVED_1A, val);
26*60907013SMarek Behún 	if (err)
27*60907013SMarek Behún 		return err;
28*60907013SMarek Behún 
29*60907013SMarek Behún 	ctrl = MV88E6XXX_PORT_RESERVED_1A_BUSY |
30*60907013SMarek Behún 	       MV88E6XXX_PORT_RESERVED_1A_WRITE |
31*60907013SMarek Behún 	       block << MV88E6XXX_PORT_RESERVED_1A_BLOCK_SHIFT |
32*60907013SMarek Behún 	       port << MV88E6XXX_PORT_RESERVED_1A_PORT_SHIFT |
33*60907013SMarek Behún 	       reg;
34*60907013SMarek Behún 
35*60907013SMarek Behún 	return mv88e6xxx_port_write(chip, MV88E6XXX_PORT_RESERVED_1A_CTRL_PORT,
36*60907013SMarek Behún 				    MV88E6XXX_PORT_RESERVED_1A, ctrl);
37*60907013SMarek Behún }
38*60907013SMarek Behún 
39*60907013SMarek Behún int mv88e6xxx_port_hidden_wait(struct mv88e6xxx_chip *chip)
40*60907013SMarek Behún {
41*60907013SMarek Behún 	int bit = __bf_shf(MV88E6XXX_PORT_RESERVED_1A_BUSY);
42*60907013SMarek Behún 
43*60907013SMarek Behún 	return mv88e6xxx_wait_bit(chip, MV88E6XXX_PORT_RESERVED_1A_CTRL_PORT,
44*60907013SMarek Behún 				  MV88E6XXX_PORT_RESERVED_1A, bit, 0);
45*60907013SMarek Behún }
46*60907013SMarek Behún 
47*60907013SMarek Behún int mv88e6xxx_port_hidden_read(struct mv88e6xxx_chip *chip, int block, int port,
48*60907013SMarek Behún 			       int reg, u16 *val)
49*60907013SMarek Behún {
50*60907013SMarek Behún 	u16 ctrl;
51*60907013SMarek Behún 	int err;
52*60907013SMarek Behún 
53*60907013SMarek Behún 	ctrl = MV88E6XXX_PORT_RESERVED_1A_BUSY |
54*60907013SMarek Behún 	       MV88E6XXX_PORT_RESERVED_1A_READ |
55*60907013SMarek Behún 	       block << MV88E6XXX_PORT_RESERVED_1A_BLOCK_SHIFT |
56*60907013SMarek Behún 	       port << MV88E6XXX_PORT_RESERVED_1A_PORT_SHIFT |
57*60907013SMarek Behún 	       reg;
58*60907013SMarek Behún 
59*60907013SMarek Behún 	err = mv88e6xxx_port_write(chip, MV88E6XXX_PORT_RESERVED_1A_CTRL_PORT,
60*60907013SMarek Behún 				   MV88E6XXX_PORT_RESERVED_1A, ctrl);
61*60907013SMarek Behún 	if (err)
62*60907013SMarek Behún 		return err;
63*60907013SMarek Behún 
64*60907013SMarek Behún 	err = mv88e6xxx_port_hidden_wait(chip);
65*60907013SMarek Behún 	if (err)
66*60907013SMarek Behún 		return err;
67*60907013SMarek Behún 
68*60907013SMarek Behún 	return mv88e6xxx_port_read(chip, MV88E6XXX_PORT_RESERVED_1A_DATA_PORT,
69*60907013SMarek Behún 				   MV88E6XXX_PORT_RESERVED_1A, val);
70*60907013SMarek Behún }
71