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