160907013SMarek Behún // SPDX-License-Identifier: GPL-2.0-or-later
260907013SMarek Behún /*
360907013SMarek Behún * Marvell 88E6xxx Switch Hidden Registers support
460907013SMarek Behún *
560907013SMarek Behún * Copyright (c) 2008 Marvell Semiconductor
660907013SMarek Behún *
760907013SMarek Behún * Copyright (c) 2019 Andrew Lunn <andrew@lunn.ch>
860907013SMarek Behún */
960907013SMarek Behún
1060907013SMarek Behún #include <linux/bitfield.h>
1160907013SMarek Behún
1260907013SMarek Behún #include "chip.h"
1360907013SMarek Behún #include "port.h"
1460907013SMarek Behún
1560907013SMarek Behún /* The mv88e6390 and mv88e6341 have some hidden registers used for debug and
1660907013SMarek Behún * development. The errata also makes use of them.
1760907013SMarek Behún */
mv88e6xxx_port_hidden_write(struct mv88e6xxx_chip * chip,int block,int port,int reg,u16 val)1860907013SMarek Behún int mv88e6xxx_port_hidden_write(struct mv88e6xxx_chip *chip, int block,
1960907013SMarek Behún int port, int reg, u16 val)
2060907013SMarek Behún {
2160907013SMarek Behún u16 ctrl;
2260907013SMarek Behún int err;
2360907013SMarek Behún
2460907013SMarek Behún err = mv88e6xxx_port_write(chip, MV88E6XXX_PORT_RESERVED_1A_DATA_PORT,
2560907013SMarek Behún MV88E6XXX_PORT_RESERVED_1A, val);
2660907013SMarek Behún if (err)
2760907013SMarek Behún return err;
2860907013SMarek Behún
2960907013SMarek Behún ctrl = MV88E6XXX_PORT_RESERVED_1A_BUSY |
3060907013SMarek Behún MV88E6XXX_PORT_RESERVED_1A_WRITE |
3160907013SMarek Behún block << MV88E6XXX_PORT_RESERVED_1A_BLOCK_SHIFT |
3260907013SMarek Behún port << MV88E6XXX_PORT_RESERVED_1A_PORT_SHIFT |
3360907013SMarek Behún reg;
3460907013SMarek Behún
3560907013SMarek Behún return mv88e6xxx_port_write(chip, MV88E6XXX_PORT_RESERVED_1A_CTRL_PORT,
3660907013SMarek Behún MV88E6XXX_PORT_RESERVED_1A, ctrl);
3760907013SMarek Behún }
3860907013SMarek Behún
mv88e6xxx_port_hidden_wait(struct mv88e6xxx_chip * chip)3960907013SMarek Behún int mv88e6xxx_port_hidden_wait(struct mv88e6xxx_chip *chip)
4060907013SMarek Behún {
4160907013SMarek Behún int bit = __bf_shf(MV88E6XXX_PORT_RESERVED_1A_BUSY);
4260907013SMarek Behún
43*24cbdb91SNathan Rossi return mv88e6xxx_port_wait_bit(chip,
44*24cbdb91SNathan Rossi MV88E6XXX_PORT_RESERVED_1A_CTRL_PORT,
4560907013SMarek Behún MV88E6XXX_PORT_RESERVED_1A, bit, 0);
4660907013SMarek Behún }
4760907013SMarek Behún
mv88e6xxx_port_hidden_read(struct mv88e6xxx_chip * chip,int block,int port,int reg,u16 * val)4860907013SMarek Behún int mv88e6xxx_port_hidden_read(struct mv88e6xxx_chip *chip, int block, int port,
4960907013SMarek Behún int reg, u16 *val)
5060907013SMarek Behún {
5160907013SMarek Behún u16 ctrl;
5260907013SMarek Behún int err;
5360907013SMarek Behún
5460907013SMarek Behún ctrl = MV88E6XXX_PORT_RESERVED_1A_BUSY |
5560907013SMarek Behún MV88E6XXX_PORT_RESERVED_1A_READ |
5660907013SMarek Behún block << MV88E6XXX_PORT_RESERVED_1A_BLOCK_SHIFT |
5760907013SMarek Behún port << MV88E6XXX_PORT_RESERVED_1A_PORT_SHIFT |
5860907013SMarek Behún reg;
5960907013SMarek Behún
6060907013SMarek Behún err = mv88e6xxx_port_write(chip, MV88E6XXX_PORT_RESERVED_1A_CTRL_PORT,
6160907013SMarek Behún MV88E6XXX_PORT_RESERVED_1A, ctrl);
6260907013SMarek Behún if (err)
6360907013SMarek Behún return err;
6460907013SMarek Behún
6560907013SMarek Behún err = mv88e6xxx_port_hidden_wait(chip);
6660907013SMarek Behún if (err)
6760907013SMarek Behún return err;
6860907013SMarek Behún
6960907013SMarek Behún return mv88e6xxx_port_read(chip, MV88E6XXX_PORT_RESERVED_1A_DATA_PORT,
7060907013SMarek Behún MV88E6XXX_PORT_RESERVED_1A, val);
7160907013SMarek Behún }
72